diff --git a/base/applications/calc/convert.c b/base/applications/calc/convert.c index c1de5558a94..26383080328 100644 --- a/base/applications/calc/convert.c +++ b/base/applications/calc/convert.c @@ -56,35 +56,35 @@ static const conv_t conv_ANGLE[] = { /* 1 acre ................ = 4840 square yd = 4046,8564224 mq - 1 acre brazil ......... = - 1 acre france ......... = + 1 acre brazil ......... = + 1 acre france ......... = 1 acre scots .......... = 5000 mq 1 acre us ............. = 4840*(36/39.37)^2 m = 6272640/1549.9969 m 1 are ................. = 100 mq 1 chou ................ = 108000*(10/33)^2 mq - 1 danbo ............... = + 1 danbo ............... = 1 ha .................. = 10000 mq - 1 jeongbo ............. = - 1 morgen hungary ...... = - 1 mu .................. = - 1 ping ................ = - 1 pyeong .............. = - 1 pyeongbangja ........ = - 1 rai ................. = + 1 jeongbo ............. = + 1 morgen hungary ...... = + 1 mu .................. = 2000/3 mq + 1 ping ................ = + 1 pyeong .............. = + 1 pyeongbangja ........ = + 1 rai ................. = 1600 mq 1 se .................. = 1080*(10/33)^2 mq 1 square cm ........... = 0.0001 mq - 1 square chr .......... = + 1 square chr .......... = 1 square fathom ....... = 1.8288^2 = 3.34450944 mq 1 square fathom hungary = 1.8964838^2 = 3.59665080366244 mq 1 square ft ........... = 0,09290304 mq 1 square in ........... = 0,00064516 mq 1 square km ........... = 1000000 mq - 1 square lar .......... = + 1 square lar .......... = 1 square mile ......... = 1609.344^2 = 2589988.110336 mq 1 square mm ........... = 0,000001 mq 1 square shaku ........ = (10/33)^2 mq - 1 square tsuen ........ = - 1 square va ........... = + 1 square tsuen ........ = + 1 square va ........... = 1 square yard ......... = 0,83612736 mq 1 tan ................. = 10800*(10/33)^2 mq 1 tsubo ............... = 36*(10/33)^2 mq @@ -101,11 +101,11 @@ static const conv_t conv_AREA[] = { DECLARE_CONV_UNIT(AREA, HECTARES, "$*10000", "$/10000") // DECLARE_CONV_UNIT(AREA, JEONGBO, "$", "$") // DECLARE_CONV_UNIT(AREA, MORGEN_HUNGARY, "$", "$") -// DECLARE_CONV_UNIT(AREA, MU, "$", "$") + DECLARE_CONV_UNIT(AREA, MU, "$*(2000/3)", "$/(2000/3)") // DECLARE_CONV_UNIT(AREA, PING, "$", "$") // DECLARE_CONV_UNIT(AREA, PYEONG, "$", "$") // DECLARE_CONV_UNIT(AREA, PYEONGBANGJA, "$", "$") -// DECLARE_CONV_UNIT(AREA, RAI, "$", "$") + DECLARE_CONV_UNIT(AREA, RAI, "$*1600", "$/1600") DECLARE_CONV_UNIT(AREA, SE, "$*108000/1089", "$*1089/108000") DECLARE_CONV_UNIT(AREA, SQUARE_CENTIMETERS, "$*0,0001", "$/0,0001") // DECLARE_CONV_UNIT(AREA, SQUARE_CHR, "$", "$") @@ -197,46 +197,47 @@ static const conv_t conv_ENERGY[] = { 1 barleycorn ..... = 1/3 inch = 0.9144/108 m 1 cm ............. = 1/100 m 1 chain uk ....... = 22 yards = 22*0.9144 m - 1 chi ............ = + 1 chi ............ = 1/3 m 1 chou ........... = 3600/33 m - 1 chr ............ = + 1 chr ............ = + 1 cun ............ = 1/10 chi = 1/30 m 1 fathom ......... = 2 yard = 2*0.9144 m 1 fathom ungary .. = 1.8964838 m (fixed) 1 feet ........... = 12 inch = 0.9144/3 m 1 furlong ........ = 10 chains = 220*0.9144 m - 1 gan ............ = + 1 gan ............ = 1 hand ........... = 4 inches = 0.9144/9 m - 1 hunh ........... = + 1 hunh ........... = 1 inch ........... = yard/36 = 0.9144/36 m - 1 ja ............. = - 1 jeong .......... = - 1 kabiet ......... = + 1 ja ............. = + 1 jeong .......... = + 1 kabiet ......... = 1 ken ............ = 60/33 m - 1 keub ........... = + 1 keub ........... = 1 km ............. = 1000 m - 1 lar ............ = + 1 lar ............ = 1 light year ..... = 9460730472580800 m 1 link uk ........ = 0.01 chains = 0.22*0.9144 m 1 micron ......... = 0.000001 m 1 mile ........... = 1760 yards = 1609.344 m 1 millimeter ..... = 1/1000 m 1 nautical mile .. = 1852 m - 1 nieu ........... = + 1 nieu ........... = 1 parsec ......... = 30856800000000000 m 1 pica ........... = yard/216 = 0.9144/216 m - 1 ri japan ....... = - 1 ri korea ....... = + 1 ri japan ....... = + 1 ri korea ....... = 1 rod ............ = 5.0292 m - 1 sawk ........... = - 1 sen ............ = + 1 sawk ........... = + 1 sen ............ = 1 shaku .......... = 10/33 m 1 span ........... = 9 inches = 0.9144/4 m - 1 sun ............ = 10/330 m - 1 tsuen .......... = - 1 va ............. = + 1 sun ............ = 1/33 m + 1 tsuen .......... = + 1 va ............. = 1 yard ........... = 0.9144 m - 1 yote ........... = - 1 zhang .......... = + 1 yote ........... = + 1 zhang .......... = */ static const conv_t conv_LENGTH[] = { DECLARE_CONV_UNIT(LENGTH, ANGSTROMS, "$*0.0000000001", "$/0.0000000001") @@ -244,10 +245,10 @@ static const conv_t conv_LENGTH[] = { DECLARE_CONV_UNIT(LENGTH, BARLEYCORNS, "$*0.9144/108", "$/0.9144*108") DECLARE_CONV_UNIT(LENGTH, CENTIMETERS, "$/100", "$*100") DECLARE_CONV_UNIT(LENGTH, CHAINS_UK, "$*20.1168", "$/20.1168") -// DECLARE_CONV_UNIT(LENGTH, CHI, "$", "$") + DECLARE_CONV_UNIT(LENGTH, CHI, "$/3", "$*3") DECLARE_CONV_UNIT(LENGTH, CHOU, "$*3600/33", "$*33/3600") // DECLARE_CONV_UNIT(LENGTH, CHR, "$", "$") -// DECLARE_CONV_UNIT(LENGTH, CUN, "$", "$") + DECLARE_CONV_UNIT(LENGTH, CUN, "$/30", "$*30") DECLARE_CONV_UNIT(LENGTH, FATHOMS, "$*1.8288", "$/1.8288") DECLARE_CONV_UNIT(LENGTH, FATHOMS_HUNGARY, "$*1.8964838", "$/1.8964838") DECLARE_CONV_UNIT(LENGTH, FEET, "$*0.3048", "$/0.3048") @@ -280,7 +281,7 @@ static const conv_t conv_LENGTH[] = { // DECLARE_CONV_UNIT(LENGTH, SEN, "$", "$") DECLARE_CONV_UNIT(LENGTH, SHAKU, "$*10/33", "$*33/10") DECLARE_CONV_UNIT(LENGTH, SPAN, "$*0.9144/4", "$*4/0.9144") - DECLARE_CONV_UNIT(LENGTH, SUN, "$*10/330", "$*330/10") + DECLARE_CONV_UNIT(LENGTH, SUN, "$*1/33", "$*33") // DECLARE_CONV_UNIT(LENGTH, TSUEN, "$", "$") // DECLARE_CONV_UNIT(LENGTH, VA, "$", "$") DECLARE_CONV_UNIT(LENGTH, YARDS, "$*0.9144", "$/0.9144") @@ -312,7 +313,7 @@ static const conv_t conv_POWER[] = { 1 hPa = 100 Pa 1 kPa = 1000 Pa 1 mm HG = 133.322 Pa - 1 psi = 6894.757 Pa + 1 psi = 6894.757 Pa */ static const conv_t conv_PRESSURE[] = { DECLARE_CONV_UNIT(PRESSURE, ATMOSPHERES, "$*101325", "$/101325") @@ -330,18 +331,20 @@ static const conv_t conv_PRESSURE[] = { 1 hour ...... = 3600 s 1 microsecond = 0.000001 s 1 millisecond = 0.001 s + 1 nanosecond. = 0.000000001 s 1 minute .... = 60 s 1 week ...... = 669600 s */ static const conv_t conv_TIME[] = { - DECLARE_CONV_UNIT(TIME, MINUTES, "$*60", "$/60") - DECLARE_CONV_UNIT(TIME, DAYS, "$*86400", "$/86400") - DECLARE_CONV_UNIT(TIME, HOURS, "$*3600", "$/3600") - DECLARE_CONV_UNIT(TIME, MILLISECONDS, "$*0.001", "$/0.001") - DECLARE_CONV_UNIT(TIME, MICROSECONDS, "$*0.000001", "$/0.000001") - DECLARE_CONV_UNIT(TIME, SECONDS, "$", "$") - DECLARE_CONV_UNIT(TIME, WEEKS, "$*604800", "$/604800") - DECLARE_CONV_UNIT(TIME, YEARS, "$*31556952", "$/31556952") + DECLARE_CONV_UNIT(TIME, MINUTES, "$*60", "$/60") + DECLARE_CONV_UNIT(TIME, DAYS, "$*86400", "$/86400") + DECLARE_CONV_UNIT(TIME, HOURS, "$*3600", "$/3600") + DECLARE_CONV_UNIT(TIME, MILLISECONDS, "$*0.001", "$/0.001") + DECLARE_CONV_UNIT(TIME, MICROSECONDS, "$*0.000001", "$/0.000001") + DECLARE_CONV_UNIT(TIME, NANOSECONDS, "$*0.000000001", "$/0.000000001") + DECLARE_CONV_UNIT(TIME, SECONDS, "$", "$") + DECLARE_CONV_UNIT(TIME, WEEKS, "$*604800", "$/604800") + DECLARE_CONV_UNIT(TIME, YEARS, "$*31556952", "$/31556952") DECLARE_CONV_END }; @@ -382,7 +385,7 @@ static const conv_t conv_VELOCITY[] = { /* 1 barrel uk ...... = 163.65924 l 1 barrel oil ..... = 158.987295 l - 1 bun ............ = + 1 bun ............ = 1 bushel uk ...... = 36.36872 l 1 bushel us ...... = 35.23907017 l 1 cubic cm ...... = 0.001 l @@ -390,17 +393,17 @@ static const conv_t conv_VELOCITY[] = { 1 cubic inch ..... = 0.016387064 l 1 cubic meter .... = 1000 l 1 cubic yard ..... = 764.554857 l - 1 doe ............ = + 1 doe ............ = 1 fluid ounce uk = 0.0284130625 l 1 fluid ounce us = 0.0295735295625 l 1 gallon uk ...... = 4.54609 l 1 gallon dry us .. = 4.40488377086 l 1 gallon liquid us = 3.785411784 l 1 gou ............ = 0.1809 l - 1 hop ............ = - 1 icce ........... = - 1 kwian .......... = - 1 mal ............ = + 1 hop ............ = + 1 icce ........... = + 1 kwian .......... = + 1 mal ............ = 1 milliliter ..... = 0.001 l 1 pint uk ........ = 0.56826125 l 1 pint dry us .... = 0.5506104713575 l @@ -408,10 +411,10 @@ static const conv_t conv_VELOCITY[] = { 1 quart uk ....... = 1.1365225 l 1 quart dry us ... = 1.101220942715 l 1 quart liquid us = 0.946352946 l - 1 seki ........... = - 1 syou ........... = - 1 tananloung ..... = - 1 tang ........... = + 1 seki ........... = + 1 syou ........... = + 1 tananloung ..... = + 1 tang ........... = 1 to ............. = 18040 l */ static const conv_t conv_VOLUME[] = { @@ -455,16 +458,16 @@ static const conv_t conv_VOLUME[] = { /* 1 baht ............ = 12.244 g 1 carat ........... = 0.2 g - 1 chung ........... = - 1 don ............. = - 1 geun ............ = - 1 gwan ............ = - 1 harb ............ = - 1 jin china ....... = - 1 jin taiwan ...... = - 1 Kan ............. = + 1 chung ........... = + 1 don ............. = + 1 geun ............ = + 1 gwan ............ = + 1 harb ............ = + 1 jin china ....... = + 1 jin taiwan ...... = + 1 Kan ............. = 3750 g 1 Kilograms ....... = 1000 g - 1 Kin ............. = + 1 Kin ............. = 600 g 1 Liang China ..... = 1 Liang Taiwan .... = 1 monme ........... = 3.75 g @@ -472,9 +475,9 @@ static const conv_t conv_VOLUME[] = { 1 ounce troy ...... = 31.1034768 g 1 pound ........... = 453.59237 g 1 quintal metric .. = 100000 g - 1 saloung ......... = + 1 saloung ......... = 1 stone ........... = 6350.29318 g - 1 tamlung ......... = + 1 tamlung ......... = 1 ton ............. = 1000000 g 1 ton uk .......... = 1016046.9088 g // long ton 1 ton us .......... = 907184.74 g // short ton @@ -490,9 +493,9 @@ static const conv_t conv_WEIGHT[] = { // DECLARE_CONV_UNIT(WEIGHT, HARB, "$", "$") // DECLARE_CONV_UNIT(WEIGHT, JIN_CHINA, "$", "$") // DECLARE_CONV_UNIT(WEIGHT, JIN_TAIWAN, "$", "$") -// DECLARE_CONV_UNIT(WEIGHT, KAN, "$", "$") + DECLARE_CONV_UNIT(WEIGHT, KAN, "$*3750", "$/3750") DECLARE_CONV_UNIT(WEIGHT, KILOGRAMS, "$*1000", "$/1000") -// DECLARE_CONV_UNIT(WEIGHT, KIN, "$", "$") + DECLARE_CONV_UNIT(WEIGHT, KIN, "$*600", "$/600") // DECLARE_CONV_UNIT(WEIGHT, LIANG_CHINA, "$", "$") // DECLARE_CONV_UNIT(WEIGHT, LIANG_TAIWAN, "$", "$") DECLARE_CONV_UNIT(WEIGHT, MONME, "$*3.75", "$/3.75") @@ -548,7 +551,7 @@ void ConvExecute(HWND hWnd) break; } } - + /* The units can be sorted, so I must search the exact match */ item = items; SendDlgItemMessage(hWnd, IDC_COMBO_FROM, CB_GETLBTEXT, from, (LPARAM)txt_cb); diff --git a/base/applications/calc/lang/bg-BG.rc b/base/applications/calc/lang/bg-BG.rc index dc9faab1628..19f411df033 100644 --- a/base/applications/calc/lang/bg-BG.rc +++ b/base/applications/calc/lang/bg-BG.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Äíč" IDS_TIME_HOURS "×ŕńč" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Ěčęđîńĺęóíäč" IDS_TIME_MILLISECONDS "Ěčëčńĺęóíäč" IDS_TIME_MINUTES "Ěčíóňč" diff --git a/base/applications/calc/lang/cs-CZ.rc b/base/applications/calc/lang/cs-CZ.rc index 278cc562783..c1f842282de 100644 --- a/base/applications/calc/lang/cs-CZ.rc +++ b/base/applications/calc/lang/cs-CZ.rc @@ -644,6 +644,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dny" IDS_TIME_HOURS "Hodiny" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Mikrosekundy" IDS_TIME_MILLISECONDS "Milisekundy" IDS_TIME_MINUTES "Minuty" diff --git a/base/applications/calc/lang/de-DE.rc b/base/applications/calc/lang/de-DE.rc index f6513aa6dfe..d3aa5436a8f 100644 --- a/base/applications/calc/lang/de-DE.rc +++ b/base/applications/calc/lang/de-DE.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Tagen" IDS_TIME_HOURS "Stunden" + IDS_TIME_NANOSECONDS "Nanosekunden" IDS_TIME_MICROSECONDS "Mikrosekunden" IDS_TIME_MILLISECONDS "Millisekunden" IDS_TIME_MINUTES "Minuten" diff --git a/base/applications/calc/lang/el-GR.rc b/base/applications/calc/lang/el-GR.rc index 89ce2d13c64..5f88a9465e1 100644 --- a/base/applications/calc/lang/el-GR.rc +++ b/base/applications/calc/lang/el-GR.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "ĚÝńĺň" IDS_TIME_HOURS "żńĺň" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Ěéęńďäĺőôĺńüëĺđôá" IDS_TIME_MILLISECONDS "Ěéëéäĺőôĺńüëĺđôá" IDS_TIME_MINUTES "ËĺđôÜ" diff --git a/base/applications/calc/lang/en-US.rc b/base/applications/calc/lang/en-US.rc index 756244ef64b..402991ab06d 100644 --- a/base/applications/calc/lang/en-US.rc +++ b/base/applications/calc/lang/en-US.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Days" IDS_TIME_HOURS "Hours" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconds" IDS_TIME_MILLISECONDS "Milliseconds" IDS_TIME_MINUTES "Minutes" diff --git a/base/applications/calc/lang/es-ES.rc b/base/applications/calc/lang/es-ES.rc index faba06c0b03..88e89a384fe 100644 --- a/base/applications/calc/lang/es-ES.rc +++ b/base/applications/calc/lang/es-ES.rc @@ -644,6 +644,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Días" IDS_TIME_HOURS "Horas" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsegundos" IDS_TIME_MILLISECONDS "Milisegundos" IDS_TIME_MINUTES "Minutos" diff --git a/base/applications/calc/lang/fr-FR.rc b/base/applications/calc/lang/fr-FR.rc index 4cd589992cb..8536cdb8d9d 100644 --- a/base/applications/calc/lang/fr-FR.rc +++ b/base/applications/calc/lang/fr-FR.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Jours" IDS_TIME_HOURS "Heures" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsecondes" IDS_TIME_MILLISECONDS "Millisecondes" IDS_TIME_MINUTES "Minutes" diff --git a/base/applications/calc/lang/it-IT.rc b/base/applications/calc/lang/it-IT.rc index 0294303512a..2e96c209fb5 100644 --- a/base/applications/calc/lang/it-IT.rc +++ b/base/applications/calc/lang/it-IT.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Giorni" IDS_TIME_HOURS "Ore" + IDS_TIME_NANOSECONDS "Nanosecondi" IDS_TIME_MICROSECONDS "Microsecondi" IDS_TIME_MILLISECONDS "Millisecondi" IDS_TIME_MINUTES "Minuti" diff --git a/base/applications/calc/lang/ko-KR.rc b/base/applications/calc/lang/ko-KR.rc index 51d70687527..8ab51ed6496 100644 --- a/base/applications/calc/lang/ko-KR.rc +++ b/base/applications/calc/lang/ko-KR.rc @@ -643,6 +643,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Days" IDS_TIME_HOURS "Hours" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconds" IDS_TIME_MILLISECONDS "Milliseconds" IDS_TIME_MINUTES "Minutes" diff --git a/base/applications/calc/lang/nl-NL.rc b/base/applications/calc/lang/nl-NL.rc index 510352f6ee2..bad67ab7a32 100644 --- a/base/applications/calc/lang/nl-NL.rc +++ b/base/applications/calc/lang/nl-NL.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dagen" IDS_TIME_HOURS "Uren" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconden" IDS_TIME_MILLISECONDS "Milliseconden" IDS_TIME_MINUTES "Minuten" diff --git a/base/applications/calc/lang/no-NO.rc b/base/applications/calc/lang/no-NO.rc index 3bb0857dc8e..8e590be8ac3 100644 --- a/base/applications/calc/lang/no-NO.rc +++ b/base/applications/calc/lang/no-NO.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "**" IDS_TIME_HOURS "**" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "**" IDS_TIME_MILLISECONDS "**" IDS_TIME_MINUTES "**" diff --git a/base/applications/calc/lang/pl-PL.rc b/base/applications/calc/lang/pl-PL.rc index 8fdfa4bdad9..59cf444ef50 100644 --- a/base/applications/calc/lang/pl-PL.rc +++ b/base/applications/calc/lang/pl-PL.rc @@ -464,9 +464,9 @@ END // TYPES OF ANGLES STRINGTABLE DISCARDABLE BEGIN - IDS_ANGLE_DEGREES "Stopni" - IDS_ANGLE_GRADIANS "Gradianów" - IDS_ANGLE_RADIANS "Radianów" + IDS_ANGLE_DEGREES "Stopnie" + IDS_ANGLE_GRADIANS "Gradiany" + IDS_ANGLE_RADIANS "Radiany" END // TYPES OF AREAS @@ -489,21 +489,21 @@ BEGIN IDS_AREA_PYEONGBANGJA "Pyeongbangja" IDS_AREA_RAI "Rai" IDS_AREA_SE "Se" - IDS_AREA_SQUARE_CENTIMETERS "Centymetrów kwadratowych" - IDS_AREA_SQUARE_CHR "Chr kwadratowych" - IDS_AREA_SQUARE_FATHOMS "Sążni kwadratowych" - IDS_AREA_SQUARE_FATHOMS_HUNGARY "Sążni kwadratowych (Węgry)" - IDS_AREA_SQUARE_FEET "Stóp kwadratowych" - IDS_AREA_SQUARE_INCHES "Cali kwadratowych" - IDS_AREA_SQUARE_KILOMETERS "Kilometrów kwadratowych" - IDS_AREA_SQUARE_LAR "Lar kwadratowych" - IDS_AREA_SQUARE_METER "Metrów kwadratowych" - IDS_AREA_SQUARE_MILES "Mil kwadratowych" - IDS_AREA_SQUARE_MILLIMETERS "Milimetrów kwadratowych" - IDS_AREA_SQUARE_SHAKU "Shaku kwadratowych" - IDS_AREA_SQUARE_TSUEN "Tsuen kwadratowych" - IDS_AREA_SQUARE_VA "Va kwadratowych" - IDS_AREA_SQUARE_YARD "Jardów kwadratowych" + IDS_AREA_SQUARE_CENTIMETERS "Centymetry kwadratowe" + IDS_AREA_SQUARE_CHR "Chr kwadratowe" + IDS_AREA_SQUARE_FATHOMS "Sążnie kwadratowe" + IDS_AREA_SQUARE_FATHOMS_HUNGARY "Sążnie kwadratowe (Węgry)" + IDS_AREA_SQUARE_FEET "Stopy kwadratowe" + IDS_AREA_SQUARE_INCHES "Cale kwadratowe" + IDS_AREA_SQUARE_KILOMETERS "Kilometry kwadratowe" + IDS_AREA_SQUARE_LAR "Lar kwadratowe" + IDS_AREA_SQUARE_METER "Metry kwadratowe" + IDS_AREA_SQUARE_MILES "Mile kwadratowe" + IDS_AREA_SQUARE_MILLIMETERS "Milimetry kwadratowe" + IDS_AREA_SQUARE_SHAKU "Shaku kwadratowe" + IDS_AREA_SQUARE_TSUEN "Tsuen kwadratowe" + IDS_AREA_SQUARE_VA "Va kwadratowe" + IDS_AREA_SQUARE_YARD "Jardy kwadratowe" IDS_AREA_TAN "Tan" IDS_AREA_TSUBO "Tsubo" END @@ -511,10 +511,10 @@ END // TYPES OF COMSUMPTIONS STRINGTABLE DISCARDABLE BEGIN - IDS_CONSUMPTION_KM_PER_L "Kilometrów/litr" - IDS_CONSUMPTION_L_PER_100_KM "Litrów/100 kilometróws" - IDS_CONSUMPTION_MILES_GALLON_UK "Mil/galon (UK)" - IDS_CONSUMPTION_MILES_GALLON_US "Mil/galon (USA)" + IDS_CONSUMPTION_KM_PER_L "Kilometry/litr" + IDS_CONSUMPTION_L_PER_100_KM "Litry/100 kilometrów" + IDS_CONSUMPTION_MILES_GALLON_UK "Mile/galon (UK)" + IDS_CONSUMPTION_MILES_GALLON_US "Mile/galon (USA)" END // TYPES OF CURRENCIES @@ -543,56 +543,56 @@ END // TYPES OF ENERGIES STRINGTABLE DISCARDABLE BEGIN - IDS_ENERGY_15_C_CALORIES "15 °C kalorii" + IDS_ENERGY_15_C_CALORIES "15 °C kalorie" IDS_ENERGY_BTUS "British Thermal Unit" - IDS_ENERGY_ERGS "Ergów" - IDS_ENERGY_EVS "Elektronowolt" - IDS_ENERGY_FOOT_POUNDS "Foot-pound" + IDS_ENERGY_ERGS "Ergi" + IDS_ENERGY_EVS "Elektronowolty" + IDS_ENERGY_FOOT_POUNDS "Stopo-funty" IDS_ENERGY_IT_CALORIES "Międzynarodowa Tablica kalorii" IDS_ENERGY_IT_KILOCALORIES "Międzynarodowa Tablica kilokalorii" - IDS_ENERGY_JOULES "Dżuli" - IDS_ENERGY_KILOJOULES "Kilodżuli" - IDS_ENERGY_KILOWATT_HOURS "Kilowatogodzin" - IDS_ENERGY_NUTRITION_CALORIES "Kalorii spożywczych" - IDS_ENERGY_TH_CALORIES "Kalorii termochemicznych" + IDS_ENERGY_JOULES "Dżule" + IDS_ENERGY_KILOJOULES "Kilodżule" + IDS_ENERGY_KILOWATT_HOURS "Kilowatogodziny" + IDS_ENERGY_NUTRITION_CALORIES "Kalorie spożywcze" + IDS_ENERGY_TH_CALORIES "Kalorie termochemiczne" END // TYPES OF LENGTHS STRINGTABLE DISCARDABLE BEGIN - IDS_LENGTH_ANGSTROMS "Angsztremów" - IDS_LENGTH_ASTRONOMICAL_UNITS "Jednostek Astronomicznych" - IDS_LENGTH_BARLEYCORNS "Palców" - IDS_LENGTH_CENTIMETERS "Centimetrów" + IDS_LENGTH_ANGSTROMS "Angsztremy" + IDS_LENGTH_ASTRONOMICAL_UNITS "Jednostki Astronomiczne" + IDS_LENGTH_BARLEYCORNS "Palce" + IDS_LENGTH_CENTIMETERS "Centymetry" IDS_LENGTH_CHAINS_UK "Chains (UK)" IDS_LENGTH_CHI "Chi" IDS_LENGTH_CHOU "Chou" IDS_LENGTH_CHR "Chr" IDS_LENGTH_CUN "Cun" - IDS_LENGTH_FATHOMS "Sążni" - IDS_LENGTH_FATHOMS_HUNGARY "Sążni (Węgry)" - IDS_LENGTH_FEET "Stóp" + IDS_LENGTH_FATHOMS "Sążnie" + IDS_LENGTH_FATHOMS_HUNGARY "Sążnie (Węgry)" + IDS_LENGTH_FEET "Stopy" IDS_LENGTH_FURLONGS "Furlongs" IDS_LENGTH_GAN "Gan" - IDS_LENGTH_HANDS "Dłoni" + IDS_LENGTH_HANDS "Dłonie" IDS_LENGTH_HUNH "Hunh" - IDS_LENGTH_INCHES "Cali" + IDS_LENGTH_INCHES "Cale" IDS_LENGTH_JA "Ja" IDS_LENGTH_JEONG "Jeong" IDS_LENGTH_KABIET "Kabiet" IDS_LENGTH_KEN "Ken" IDS_LENGTH_KEUB "Keub" - IDS_LENGTH_KILOMETERS "Kilometerów" + IDS_LENGTH_KILOMETERS "Kilometry" IDS_LENGTH_LAR "Lar" - IDS_LENGTH_LIGHT_YEARS "Lat świetlnych" + IDS_LENGTH_LIGHT_YEARS "Lata świetlne" IDS_LENGTH_LINKS_UK "Links (UK)" - IDS_LENGTH_METERS "Metrów" - IDS_LENGTH_MICRONS "Mikrometrów" - IDS_LENGTH_MILES "Mil" - IDS_LENGTH_MILLIMETERS "Millimetrów" - IDS_LENGTH_NAUTICAL_MILES "Mil morskich" + IDS_LENGTH_METERS "Metry" + IDS_LENGTH_MICRONS "Mikrometry" + IDS_LENGTH_MILES "Mile" + IDS_LENGTH_MILLIMETERS "Milimetry" + IDS_LENGTH_NAUTICAL_MILES "Mile morskie" IDS_LENGTH_NIEU "Nieu" - IDS_LENGTH_PARSECS "Parseków" + IDS_LENGTH_PARSECS "Parseki" IDS_LENGTH_PICAS "Picas" IDS_LENGTH_RI_JAPAN "Ri (Japan)" IDS_LENGTH_RI_KOREA "Ri (Korea)" @@ -604,7 +604,7 @@ BEGIN IDS_LENGTH_SUN "Sun" IDS_LENGTH_TSUEN "Tsuen" IDS_LENGTH_VA "Va" - IDS_LENGTH_YARDS "Jardów" + IDS_LENGTH_YARDS "Jardy" IDS_LENGTH_YOTE "Yote" IDS_LENGTH_ZHANG "Zhang" END @@ -613,23 +613,23 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_POWER_BTUS_PER_MINUTE "BTU na minutę" - IDS_POWER_FPS_PER_MINUTE "Foot-pound na minutę" - IDS_POWER_HORSEPOWER "Koni mechanicznych" - IDS_POWER_KILOWATTS "Kilowatów" - IDS_POWER_MEGAWATTS "Megawatów" - IDS_POWER_WATTS "Watów" + IDS_POWER_FPS_PER_MINUTE "Stopo-funty na minutę" + IDS_POWER_HORSEPOWER "Konie mechaniczne" + IDS_POWER_KILOWATTS "Kilowaty" + IDS_POWER_MEGAWATTS "Megawaty" + IDS_POWER_WATTS "Waty" END // TYPE OF PRESSURES STRINGTABLE DISCARDABLE BEGIN - IDS_PRESSURE_ATMOSPHERES "Atmosfer" - IDS_PRESSURE_BARS "Barów" - IDS_PRESSURE_HECTOPASCALS "Hektopaskali" - IDS_PRESSURE_KILOPASCALS "Kilopaskali" - IDS_PRESSURE_MM_OF_MERCURY "Millimetrów słupka rtęci" - IDS_PRESSURE_PASCALS "Paskali" - IDS_PRESSURE_PSI "Funtów na cal kwadratowy" + IDS_PRESSURE_ATMOSPHERES "Atmosfery" + IDS_PRESSURE_BARS "Bary" + IDS_PRESSURE_HECTOPASCALS "Hektopaskale" + IDS_PRESSURE_KILOPASCALS "Kilopaskale" + IDS_PRESSURE_MM_OF_MERCURY "Milimetry słupka rtęci" + IDS_PRESSURE_PASCALS "Paskale" + IDS_PRESSURE_PSI "Funty na cal kwadratowy" END // TYPES OF TEMPERATURES @@ -645,60 +645,61 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dni" - IDS_TIME_HOURS "Godzin" - IDS_TIME_MICROSECONDS "Mikrosekund" - IDS_TIME_MILLISECONDS "Milisekund" - IDS_TIME_MINUTES "Minut" - IDS_TIME_SECONDS "Sekund" - IDS_TIME_WEEKS "Tygodni" - IDS_TIME_YEARS "Lat" + IDS_TIME_HOURS "Godziny" + IDS_TIME_NANOSECONDS "Nanosekundy" + IDS_TIME_MICROSECONDS "Mikrosekundy" + IDS_TIME_MILLISECONDS "Milisekundy" + IDS_TIME_MINUTES "Minuty" + IDS_TIME_SECONDS "Sekundy" + IDS_TIME_WEEKS "Tygodnie" + IDS_TIME_YEARS "Lata" END // TYPES OF VELOCITIES STRINGTABLE DISCARDABLE BEGIN - IDS_VELOCITY_CMS_SECOND "Centimetrów/sekundę" - IDS_VELOCITY_FEET_HOUR "Stóp/godzinę" - IDS_VELOCITY_FEET_SECOND "Stóp/sekundę" - IDS_VELOCITY_KILOMETERS_HOUR "Kilometrów/godzinę" - IDS_VELOCITY_KNOTS "Węzłów" - IDS_VELOCITY_MACH "Machów" - IDS_VELOCITY_METERS_SECOND "Metrów/sekundę" - IDS_VELOCITY_MILES_HOUR "Mil/godzinę" + IDS_VELOCITY_CMS_SECOND "Centymetry/sekundę" + IDS_VELOCITY_FEET_HOUR "Stopy/godzinę" + IDS_VELOCITY_FEET_SECOND "Stopy/sekundę" + IDS_VELOCITY_KILOMETERS_HOUR "Kilometry/godzinę" + IDS_VELOCITY_KNOTS "Węzły" + IDS_VELOCITY_MACH "Machy" + IDS_VELOCITY_METERS_SECOND "Metry/sekundę" + IDS_VELOCITY_MILES_HOUR "Mile/godzinę" END // TYPES OF VOLUMES STRINGTABLE DISCARDABLE BEGIN - IDS_VOLUME_BARRELS_UK "Baryłek (UK)" - IDS_VOLUME_BARRELS_OIL "Baryłek" + IDS_VOLUME_BARRELS_UK "Baryłki (UK)" + IDS_VOLUME_BARRELS_OIL "Baryłki" IDS_VOLUME_BUN "Bun" - IDS_VOLUME_BUSHELS_UK "Buszli (UK)" - IDS_VOLUME_BUSHELS_US "Buszli (US)" - IDS_VOLUME_CUBIC_CENTIMETERS "Centymetrów sześciennych" - IDS_VOLUME_CUBIC_FEET "Stóp sześciennych" - IDS_VOLUME_CUBIC_INCHES "Cali sześciennych" - IDS_VOLUME_CUBIC_METERS "Metrów sześciennych" - IDS_VOLUME_CUBIC_YARDS "Jardów sześciennych" + IDS_VOLUME_BUSHELS_UK "Buszle (UK)" + IDS_VOLUME_BUSHELS_US "Buszle (US)" + IDS_VOLUME_CUBIC_CENTIMETERS "Centymetry sześcienne" + IDS_VOLUME_CUBIC_FEET "Stopy sześcienne" + IDS_VOLUME_CUBIC_INCHES "Cale sześcienne" + IDS_VOLUME_CUBIC_METERS "Metry sześcienne" + IDS_VOLUME_CUBIC_YARDS "Jardy sześcienne" IDS_VOLUME_DOE "Doe" - IDS_VOLUME_FLUID_OUNCES_UK "Uncji, płyn (UK)" - IDS_VOLUME_FLUID_OUNCES_US "Uncji, płyn (US)" - IDS_VOLUME_GALLONS_UK "Galonów (UK)" - IDS_VOLUME_GALLONS_DRY_US "Galonów, sypkie (US)" - IDS_VOLUME_GALLONS_LIQUID_US "Gallons, płyn (US)" + IDS_VOLUME_FLUID_OUNCES_UK "Uncje, płyn (UK)" + IDS_VOLUME_FLUID_OUNCES_US "Uncje, płyn (US)" + IDS_VOLUME_GALLONS_UK "Galony (UK)" + IDS_VOLUME_GALLONS_DRY_US "Galony, sypkie (US)" + IDS_VOLUME_GALLONS_LIQUID_US "Galony, płyn (US)" IDS_VOLUME_GOU "Gou" IDS_VOLUME_HOP "Hop" IDS_VOLUME_ICCE "Icce" IDS_VOLUME_KWIAN "Kwian" - IDS_VOLUME_LITERS "Litrów" + IDS_VOLUME_LITERS "Litry" IDS_VOLUME_MAL "Mal" - IDS_VOLUME_MILLILITERS "Milliliters" - IDS_VOLUME_PINTS_UK "Pint (UK)" - IDS_VOLUME_PINTS_DRY_US "Pint, sypkie (US)" - IDS_VOLUME_PINTS_LIQUID_US "Pint, płyn (US)" - IDS_VOLUME_QUARTS_UK "Kwart (UK)" - IDS_VOLUME_QUARTS_DRY_US "Kwart, sypkie (US)" - IDS_VOLUME_QUARTS_LIQUID_US "Kwart, płyn (US)" + IDS_VOLUME_MILLILITERS "Mililitry" + IDS_VOLUME_PINTS_UK "Pinty (UK)" + IDS_VOLUME_PINTS_DRY_US "Pinty, sypkie (US)" + IDS_VOLUME_PINTS_LIQUID_US "Pinty, płyn (US)" + IDS_VOLUME_QUARTS_UK "Kwarty (UK)" + IDS_VOLUME_QUARTS_DRY_US "Kwarty, sypkie (US)" + IDS_VOLUME_QUARTS_LIQUID_US "Kwarty, płyn (US)" IDS_VOLUME_SEKI "Seki" IDS_VOLUME_SYOU "Syou" IDS_VOLUME_TANANLOUNG "Tananloung" @@ -709,26 +710,26 @@ END // TYPES OF WEIGHTS STRINGTABLE DISCARDABLE BEGIN - IDS_WEIGHT_BAHT "Bahtów" - IDS_WEIGHT_CARATS "Karatów" + IDS_WEIGHT_BAHT "Bahty" + IDS_WEIGHT_CARATS "Karaty" IDS_WEIGHT_CHUNG "Chung" IDS_WEIGHT_DON "Don" IDS_WEIGHT_GEUN "Geun" - IDS_WEIGHT_GRAMS "Gramów" + IDS_WEIGHT_GRAMS "Gramy" IDS_WEIGHT_GWAN "Gwan" IDS_WEIGHT_HARB "Harb" IDS_WEIGHT_JIN_CHINA "Jin (China)" IDS_WEIGHT_JIN_TAIWAN "Jin (Taiwan)" IDS_WEIGHT_KAN "Kan" - IDS_WEIGHT_KILOGRAMS "Kilogramów" + IDS_WEIGHT_KILOGRAMS "Kilogramy" IDS_WEIGHT_KIN "Kin" IDS_WEIGHT_LIANG_CHINA "Liang (China)" IDS_WEIGHT_LIANG_TAIWAN "Liang (Taiwan)" IDS_WEIGHT_MONME "Monme" - IDS_WEIGHT_OUNCES_AVOIRDUPOIS "Uncji, avoirdupois" - IDS_WEIGHT_OUNCES_TROY "Uncji, aptekarskie" - IDS_WEIGHT_POUNDS "Funtów" - IDS_WEIGHT_QUINTAL_METRIC "Kwintali" + IDS_WEIGHT_OUNCES_AVOIRDUPOIS "Uncje, avoirdupois" + IDS_WEIGHT_OUNCES_TROY "Uncje, aptekarskie" + IDS_WEIGHT_POUNDS "Funty" + IDS_WEIGHT_QUINTAL_METRIC "Kwintale" IDS_WEIGHT_SALOUNG "Saloung" IDS_WEIGHT_STONES "Kamieni" IDS_WEIGHT_TAMLUNG "Tamlung" diff --git a/base/applications/calc/lang/ro-RO.rc b/base/applications/calc/lang/ro-RO.rc index 1680780befb..4c353ea9c0f 100644 --- a/base/applications/calc/lang/ro-RO.rc +++ b/base/applications/calc/lang/ro-RO.rc @@ -641,6 +641,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Zile" IDS_TIME_HOURS "Ore" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microsecunde" IDS_TIME_MILLISECONDS "Milisecunde" IDS_TIME_MINUTES "Minute" diff --git a/base/applications/calc/lang/ru-RU.rc b/base/applications/calc/lang/ru-RU.rc index 63b478b2f33..6d2d41c3612 100644 --- a/base/applications/calc/lang/ru-RU.rc +++ b/base/applications/calc/lang/ru-RU.rc @@ -639,6 +639,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "äĺíü" IDS_TIME_HOURS "÷ŕń" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "ěčęđîńĺęóíäŕ" IDS_TIME_MILLISECONDS "ěčëëčńĺęóíäŕ" IDS_TIME_MINUTES "ěčíóňŕ" diff --git a/base/applications/calc/lang/sk-SK.rc b/base/applications/calc/lang/sk-SK.rc index 3f93b953ef0..4951a860320 100644 --- a/base/applications/calc/lang/sk-SK.rc +++ b/base/applications/calc/lang/sk-SK.rc @@ -647,6 +647,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Dni" IDS_TIME_HOURS "Hodiny" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Mikrosekundy" IDS_TIME_MILLISECONDS "Milisekundy" IDS_TIME_MINUTES "Minúty" diff --git a/base/applications/calc/lang/th-TH.rc b/base/applications/calc/lang/th-TH.rc index 214bd80b185..ade4a12b17e 100644 --- a/base/applications/calc/lang/th-TH.rc +++ b/base/applications/calc/lang/th-TH.rc @@ -644,6 +644,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Days" IDS_TIME_HOURS "Hours" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Microseconds" IDS_TIME_MILLISECONDS "Milliseconds" IDS_TIME_MINUTES "Minutes" diff --git a/base/applications/calc/lang/uk-UA.rc b/base/applications/calc/lang/uk-UA.rc index b4c7f19c933..9d73142142a 100644 --- a/base/applications/calc/lang/uk-UA.rc +++ b/base/applications/calc/lang/uk-UA.rc @@ -647,6 +647,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_TIME_DAYS "Äîáŕ" IDS_TIME_HOURS "Ăîäčíŕ" + IDS_TIME_NANOSECONDS "Nanoseconds" IDS_TIME_MICROSECONDS "Ěłęđîńĺęóíäŕ" IDS_TIME_MILLISECONDS "Ěłëłńĺęóíäŕ" IDS_TIME_MINUTES "Őâčëčíŕ" diff --git a/base/applications/calc/resource.h b/base/applications/calc/resource.h index 1886cc74109..8039671361e 100644 --- a/base/applications/calc/resource.h +++ b/base/applications/calc/resource.h @@ -276,10 +276,11 @@ #define IDS_TIME_HOURS 3002 #define IDS_TIME_MICROSECONDS 3003 #define IDS_TIME_MILLISECONDS 3004 -#define IDS_TIME_MINUTES 3005 -#define IDS_TIME_SECONDS 3006 -#define IDS_TIME_WEEKS 3007 -#define IDS_TIME_YEARS 3008 +#define IDS_TIME_NANOSECONDS 3005 +#define IDS_TIME_MINUTES 3006 +#define IDS_TIME_SECONDS 3007 +#define IDS_TIME_WEEKS 3008 +#define IDS_TIME_YEARS 3009 /* TYPES OF VELOCITIES */ #define IDS_VELOCITY_CMS_SECOND 3100 diff --git a/base/applications/calc/utl.c b/base/applications/calc/utl.c index 599115e9883..9ec8bebcc8f 100644 --- a/base/applications/calc/utl.c +++ b/base/applications/calc/utl.c @@ -2,7 +2,6 @@ void prepare_rpn_result_2(calc_number_t *rpn, TCHAR *buffer, int size, int base) { - TCHAR *ptr, *dst; calc_number_t tmp; int width; @@ -21,9 +20,12 @@ void prepare_rpn_result_2(calc_number_t *rpn, TCHAR *buffer, int size, int base) /* calculate the width of integer number */ width = (rpn->f==0) ? 1 : (int)log10(fabs(rpn->f))+1; if (calc.sci_out == TRUE || width > MAX_LD_WIDTH || width < -MAX_LD_WIDTH) - ptr = buffer + _stprintf(buffer, TEXT("%#e"), rpn->f); + _stprintf(buffer, TEXT("%#e"), rpn->f); else { + TCHAR *ptr, *dst; + ptr = buffer + _stprintf(buffer, TEXT("%#*.*f"), width, ((MAX_LD_WIDTH-width-1)>=0) ? MAX_LD_WIDTH-width-1 : 0, rpn->f); + /* format sring ensures there is a '.': */ dst = _tcschr(buffer, TEXT('.')); while (--ptr > dst) if (*ptr != TEXT('0')) diff --git a/base/applications/calc/winmain.c b/base/applications/calc/winmain.c index 40a34682b62..6279d3d5091 100644 --- a/base/applications/calc/winmain.c +++ b/base/applications/calc/winmain.c @@ -861,18 +861,18 @@ static INT_PTR CALLBACK DlgStatProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) n = SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_GETCURSEL, 0, 0); if (n == (DWORD)-1) return TRUE; - PostMessage(GetParent(hWnd), WM_LOAD_STAT, (WPARAM)n, 0); + PostMessage(GetParent(hWnd), WM_LOAD_STAT, (WPARAM)n, 0); return TRUE; case IDC_BUTTON_CD: n = SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_GETCURSEL, 0, 0); if (n == (DWORD)-1) return TRUE; - SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_DELETESTRING, (WPARAM)n, 0); + SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_DELETESTRING, (WPARAM)n, 0); update_n_stats_items(hWnd, buffer); delete_stat_item(n); return TRUE; case IDC_BUTTON_CAD: - SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hWnd, IDC_LIST_STAT, LB_RESETCONTENT, 0, 0); clean_stat_list(); update_n_stats_items(hWnd, buffer); return TRUE; @@ -910,20 +910,20 @@ static WPARAM idm_2_idc(int idm) static void CopyMemToClipboard(void *ptr) { if(OpenClipboard(NULL)) { - HGLOBAL clipbuffer; - TCHAR *buffer; + HGLOBAL clipbuffer; + TCHAR *buffer; - EmptyClipboard(); - clipbuffer = GlobalAlloc(GMEM_DDESHARE, (_tcslen(ptr)+1)*sizeof(TCHAR)); - buffer = (TCHAR *)GlobalLock(clipbuffer); - _tcscpy(buffer, ptr); - GlobalUnlock(clipbuffer); + EmptyClipboard(); + clipbuffer = GlobalAlloc(GMEM_DDESHARE, (_tcslen(ptr)+1)*sizeof(TCHAR)); + buffer = (TCHAR *)GlobalLock(clipbuffer); + _tcscpy(buffer, ptr); + GlobalUnlock(clipbuffer); #ifdef UNICODE - SetClipboardData(CF_UNICODETEXT,clipbuffer); + SetClipboardData(CF_UNICODETEXT,clipbuffer); #else - SetClipboardData(CF_TEXT,clipbuffer); + SetClipboardData(CF_TEXT,clipbuffer); #endif - CloseClipboard(); + CloseClipboard(); } } @@ -942,16 +942,16 @@ static char *ReadClipboard(void) char *buffer = NULL; if (OpenClipboard(NULL)) { - HANDLE hData = GetClipboardData(CF_TEXT); + HANDLE hData = GetClipboardData(CF_TEXT); char *fromClipboard; if (hData != NULL) { fromClipboard = (char *)GlobalLock(hData); if (strlen(fromClipboard)) - buffer = _strupr(_strdup(fromClipboard)); - GlobalUnlock( hData ); + buffer = _strupr(_strdup(fromClipboard)); + GlobalUnlock( hData ); } - CloseClipboard(); + CloseClipboard(); } return buffer; } @@ -1110,20 +1110,20 @@ static void handle_context_menu(HWND hWnd, WPARAM wp, LPARAM lp) { TCHAR text[64]; HMENU hMenu = CreatePopupMenu(); - DWORD idm; + BOOL idm; LoadString(calc.hInstance, IDS_QUICKHELP, text, SIZEOF(text)); AppendMenu(hMenu, MF_STRING | MF_ENABLED, IDM_HELP_HELP, text); - idm = (DWORD)TrackPopupMenu(hMenu, - TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, - LOWORD(lp), - HIWORD(lp), - 0, - hWnd, - NULL); + idm = TrackPopupMenu( hMenu, + TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, + LOWORD(lp), + HIWORD(lp), + 0, + hWnd, + NULL); DestroyMenu(hMenu); #ifndef DISABLE_HTMLHELP_SUPPORT - if (idm != 0) { + if (idm) { HH_POPUP popup; memset(&popup, 0, sizeof(popup)); @@ -1139,6 +1139,8 @@ static void handle_context_menu(HWND hWnd, WPARAM wp, LPARAM lp) popup.idString = GetWindowLongPtr((HWND)wp, GWL_ID); HtmlHelp((HWND)wp, HTMLHELP_PATH("/popups.txt"), HH_DISPLAY_TEXT_POPUP, (DWORD_PTR)&popup); } +#else + (void)idm; #endif } diff --git a/base/applications/dxdiag/ddtest.c b/base/applications/dxdiag/ddtest.c index 47f41a54ec0..734f166d9e5 100644 --- a/base/applications/dxdiag/ddtest.c +++ b/base/applications/dxdiag/ddtest.c @@ -151,7 +151,7 @@ BOOL DDPrimarySurfaceTest(HWND hWnd){ { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_TIMER && TimerID == msg.wParam) + if (msg.message == WM_TIMER && TimerID == msg.wParam) break; TranslateMessage(&msg); DispatchMessage(&msg); @@ -200,7 +200,7 @@ VOID DDRedrawFrame(LPDIRECTDRAWSURFACE lpDDSurface) BOOL DDOffscreenBufferTest(HWND hWnd, BOOL Fullscreen){ - UINT TimerID, TimerIDUpdate; + UINT_PTR TimerID, TimerIDUpdate; LPDIRECTDRAW lpDD; LPDIRECTDRAWSURFACE lpDDPrimarySurface; LPDIRECTDRAWSURFACE lpDDBackBuffer; @@ -288,6 +288,7 @@ BOOL DDOffscreenBufferTest(HWND hWnd, BOOL Fullscreen){ /* set our timers, TimerID - for test timeout, TimerIDUpdate - for frame updating */ TimerID = SetTimer(hWnd, -1, (UINT)TEST_DURATION, NULL); TimerIDUpdate = SetTimer(hWnd, 2, (UINT)10, NULL); + (void)TimerIDUpdate; while (TRUE) { diff --git a/base/applications/dxdiag/input.c b/base/applications/dxdiag/input.c index 08bb2b718b8..03d238a57ce 100644 --- a/base/applications/dxdiag/input.c +++ b/base/applications/dxdiag/input.c @@ -129,13 +129,13 @@ BOOL CALLBACK DirectInputEnumDevCb( ZeroMemory(&GuidPath, sizeof(DIPROPGUIDANDPATH)); GuidPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH); GuidPath.diph.dwHeaderSize = sizeof(DIPROPHEADER); - GuidPath.diph.dwHow = DIPH_DEVICE; + GuidPath.diph.dwHow = DIPH_DEVICE; hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GUIDANDPATH, (LPDIPROPHEADER)&GuidPath); ZeroMemory(&TypeName, sizeof(TypeName)); TypeName.diph.dwSize = sizeof(TypeName); TypeName.diph.dwHeaderSize = sizeof(DIPROPHEADER); - TypeName.diph.dwHow = DIPH_DEVICE; + TypeName.diph.dwHow = DIPH_DEVICE; hResult = pDev->lpVtbl->GetProperty(pDev, DIPROP_GETPORTDISPLAYNAME, (LPDIPROPHEADER)&TypeName); @@ -191,7 +191,7 @@ InitializeDirectInputDialog(HWND hwndDlg) Context.pObj = pObj; Context.hwndDlg = hwndDlg; InitListViewColumns(&Context); - hResult = pObj->lpVtbl->EnumDevices(pObj, DI8DEVCLASS_ALL, DirectInputEnumDevCb, (PVOID)&Context, DIEDFL_ALLDEVICES); + pObj->lpVtbl->EnumDevices(pObj, DI8DEVCLASS_ALL, DirectInputEnumDevCb, (PVOID)&Context, DIEDFL_ALLDEVICES); pObj->lpVtbl->Release(pObj); } diff --git a/base/applications/dxdiag/network.c b/base/applications/dxdiag/network.c index 5154c4eef87..3a4b7c666f2 100644 --- a/base/applications/dxdiag/network.c +++ b/base/applications/dxdiag/network.c @@ -178,10 +178,10 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv { DWORD dwIndex = 0; LONG result; - WCHAR szName[50]; + WCHAR szName[50]; WCHAR szGUID[40]; WCHAR szTemp[63]; - WCHAR szResult[MAX_PATH+20] = {0}; + WCHAR szResult[MAX_PATH+20] = {0}; DWORD RegProviders = 0; DWORD ProviderIndex; DWORD dwName; @@ -203,13 +203,12 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv szResult[0] = L'\0'; LoadStringW(hInst, PreDefProviders[dwIndex].ResourceID, szResult, sizeof(szResult)/sizeof(WCHAR)); szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0'; - lResult = SendMessageW(hDlgCtrl, LVM_INSERTITEM, 0, (LPARAM)&Item); + Item.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEM, 0, (LPARAM)&Item); + Item.iSubItem = 1; szResult[0] = L'\0'; LoadStringW(hInst, IDS_REG_FAIL, szResult, sizeof(szResult)/sizeof(WCHAR)); szResult[(sizeof(szResult)/sizeof(WCHAR))-1] = L'\0'; - Item.iItem = lResult; - Item.iSubItem = 1; - lResult = SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item); + SendMessageW(hDlgCtrl, LVM_SETITEM, 0, (LPARAM)&Item); } dwIndex = 0; @@ -228,8 +227,7 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv if (ProviderIndex == UINT_MAX) { /* a custom service provider was found */ - lResult = ListView_GetItemCount(hDlgCtrl); - Item.iItem = lResult; + Item.iItem = ListView_GetItemCount(hDlgCtrl); /* FIXME * on Windows Vista we need to use RegLoadMUIString which is not available for older systems @@ -291,7 +289,7 @@ EnumerateServiceProviders(HKEY hKey, HWND hDlgCtrl, DIRECTPLAY_GUID * PreDefProv } } dwIndex++; - }while(result != ERROR_NO_MORE_ITEMS); + }while(result != ERROR_NO_MORE_ITEMS); /* check if all providers have been registered */ // if (RegProviders == 15) @@ -330,7 +328,7 @@ InitializeDirectPlayDialog(HWND hwndDlg) return; /* enumerate providers */ - result = EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlaySP); + EnumerateServiceProviders(hKey, hDlgCtrl, DirectPlaySP); RegCloseKey(hKey); } diff --git a/base/applications/dxdiag/sound.c b/base/applications/dxdiag/sound.c index 6db11c66540..4a84c9c6342 100644 --- a/base/applications/dxdiag/sound.c +++ b/base/applications/dxdiag/sound.c @@ -275,6 +275,7 @@ void InitializeDirectSoundPage(PDXDIAG_CONTEXT pContext) /* release the DSound object */ // pObj->lpVtbl->Release(pObj); + (void)hResult; } diff --git a/base/applications/fontview/display.c b/base/applications/fontview/display.c index 1362e4a822a..55272eec754 100644 --- a/base/applications/fontview/display.c +++ b/base/applications/fontview/display.c @@ -103,7 +103,7 @@ Display_DrawText(HDC hDC, DISPLAYDATA* pData, int nYPos) /* TODO: Output font info */ /* Output Character set */ - hOldFont = SelectObject(hDC, pData->hCharSetFont); + SelectObject(hDC, pData->hCharSetFont); GetTextMetrics(hDC, &tm); swprintf(szCaption, L"abcdefghijklmnopqrstuvwxyz"); TextOutW(hDC, 0, y, szCaption, wcslen(szCaption)); diff --git a/base/applications/fontview/fontview.c b/base/applications/fontview/fontview.c index 82fa44aff6a..72b183212ba 100644 --- a/base/applications/fontview/fontview.c +++ b/base/applications/fontview/fontview.c @@ -60,13 +60,10 @@ FormatString( static void ErrorMsgBox(HWND hParent, DWORD dwCaptionID, DWORD dwMessageId, ...) { - HMODULE hModule; HLOCAL hMemCaption = NULL; HLOCAL hMemText = NULL; va_list args; - hModule = GetModuleHandle(NULL); - va_start(args, dwMessageId); FormatString(FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwMessageId, 0, (LPWSTR)&hMemText, 0, &args); diff --git a/base/applications/games/winemine/lang/cs-CZ.rc b/base/applications/games/winemine/lang/cs-CZ.rc index 3f281c7b317..bd776bafc40 100644 --- a/base/applications/games/winemine/lang/cs-CZ.rc +++ b/base/applications/games/winemine/lang/cs-CZ.rc @@ -1,8 +1,8 @@ /* FILE: applications/games/winemine/lang/cs-CZ.rc * PURPOSE: Czech Language File - * TRANSLATOR: Stepan Gabriel - SGABA (sgaba@centrum.cz) + * TRANSLATORS: Stepan Gabriel - SGABA (sgaba@centrum.cz); Radek Liska aka Black_Fox (radekliska at gmail dot com) * TRANSLATED FROM: Slovak translation by Kario (kario@szm.sk) - * UPDATED: 2008-07-06 + * UPDATED: 2010-05-25 * * Czech translation * Copyleft 2007 Kario (kario@szm.sk),2008 SGABA (sgaba@centrum.cz) @@ -15,7 +15,7 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT STRINGTABLE BEGIN IDS_SECONDS, "sek." - IDS_NOBODY, "Nikdo" //windows = Anonym + IDS_NOBODY, "Bezejmenný" //windows = Anonym IDS_ABOUT, "od Joshua Thielena a vývojářů systému ReactOS" END @@ -36,15 +36,15 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Konec", IDM_EXIT END - POPUP "&Info" //windows = &Pomocník + POPUP "&Nápověda" //windows = &Pomocník BEGIN - MENUITEM "C&o je hra Miny...", IDM_ABOUT + MENUITEM "&O programu...", IDM_ABOUT END END IDD_TIMES DIALOGEX DISCARDABLE 0, 0, 200, 75 STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT -CAPTION "Nejrychlejší htedači min" +CAPTION "Nejrychlejší hledači min" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Nejlepší časy", IDNONE, 10, 10, 182, 45 @@ -66,7 +66,7 @@ STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHEL CAPTION "Blahopřeji!" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Zadejte prosím svoje jméno.", IDIGNORE, 25, 10, 150, 10 + LTEXT "Zadejte prosím svoje jméno", IDIGNORE, 25, 10, 150, 10 EDITTEXT IDC_EDITNAME, 25, 20, 110, 12 DEFPUSHBUTTON "OK", IDOK, 60, 40, 40, 15 END @@ -83,5 +83,5 @@ BEGIN EDITTEXT IDC_EDITCOLS, 49, 35, 30, 12, ES_NUMBER EDITTEXT IDC_EDITMINES, 49, 55, 30, 12, ES_NUMBER DEFPUSHBUTTON "OK", IDOK, 86, 32, 45, 15 - PUSHBUTTON "Zrušit", IDCANCEL, 86, 52, 45, 15 + PUSHBUTTON "Storno", IDCANCEL, 86, 52, 45, 15 END diff --git a/base/applications/kbswitch/kbswitch.c b/base/applications/kbswitch/kbswitch.c index 5c94c25f79a..03f196f7771 100644 --- a/base/applications/kbswitch/kbswitch.c +++ b/base/applications/kbswitch/kbswitch.c @@ -33,7 +33,6 @@ CreateTrayIcon(LPTSTR szLCID) HDC hdc, hdcsrc; HBITMAP hBitmap, hBmpNew, hBmpOld; RECT rect; - DWORD bkColor, bkText; HFONT hFontOld, hFont = NULL; ICONINFO IconInfo; HICON hIcon = NULL; @@ -63,8 +62,8 @@ CreateTrayIcon(LPTSTR szLCID) rect.bottom = 16; rect.top = 0; - bkColor = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); - bkText = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); ExtTextOut(hdc, rect.left, rect.top, ETO_OPAQUE, &rect, _T(""), 0, NULL); diff --git a/base/applications/magnify/magnifier.c b/base/applications/magnify/magnifier.c index 43816d6b5aa..4c2b4f623e9 100644 --- a/base/applications/magnify/magnifier.c +++ b/base/applications/magnify/magnifier.c @@ -295,7 +295,7 @@ void Draw(HDC aDc) // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - int wmId, wmEvent; + int wmId; switch (message) { @@ -354,7 +354,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_COMMAND: wmId = LOWORD(wParam); - wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { diff --git a/base/applications/mplay32/mplay32.c b/base/applications/mplay32/mplay32.c index 9b1b564908a..f4bd117a65f 100644 --- a/base/applications/mplay32/mplay32.c +++ b/base/applications/mplay32/mplay32.c @@ -407,7 +407,7 @@ PlayFile(HWND hwnd, LPTSTR lpFileName) MCI_PLAY_PARMS mciPlay; TCHAR szLocalFileName[MAX_PATH]; UINT FileType; - DWORD dwError; + MCIERROR mciError; if (lpFileName == NULL) { @@ -449,14 +449,14 @@ PlayFile(HWND hwnd, LPTSTR lpFileName) SetTimer(hwnd, IDT_PLAYTIMER, 100, (TIMERPROC) PlayTimerProc); - dwError = mciSendCommand(wDeviceId, MCI_SEEK, MCI_WAIT | MCI_SEEK_TO_START, 0); + mciSendCommand(wDeviceId, MCI_SEEK, MCI_WAIT | MCI_SEEK_TO_START, 0); mciPlay.dwCallback = (DWORD_PTR)hwnd; mciPlay.dwFrom = 0; mciPlay.dwTo = MaxFilePos; - dwError = mciSendCommand(wDeviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)&mciPlay); - if (dwError != 0) + mciError = mciSendCommand(wDeviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)&mciPlay); + if (mciError != 0) { MessageBox(hwnd, _T("Can't play!"), NULL, MB_OK); } @@ -641,12 +641,12 @@ MainWndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) break; case IDM_ABOUT: - { + { HICON mplayIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN)); ShellAbout(hwnd, szAppTitle, 0, mplayIcon); - DeleteObject(mplayIcon); + DeleteObject(mplayIcon); break; - } + } case IDM_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0); return 0; diff --git a/base/applications/msconfig/freeldrpage.h b/base/applications/msconfig/freeldrpage.h index 6e0331b2a4f..23b046b1849 100644 --- a/base/applications/msconfig/freeldrpage.h +++ b/base/applications/msconfig/freeldrpage.h @@ -1,3 +1,8 @@ +#ifndef _FREELDRPAGE_H_ +#define _FREELDRPAGE_H_ + extern HWND hFreeLdrPage; INT_PTR CALLBACK FreeLdrPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/base/applications/msconfig/generalpage.h b/base/applications/msconfig/generalpage.h index 408c4049dc1..19551866bc4 100644 --- a/base/applications/msconfig/generalpage.h +++ b/base/applications/msconfig/generalpage.h @@ -1,3 +1,8 @@ +#ifndef _GENERALPAGE_H_ +#define _GENERALPAGE_H_ + extern HWND hGeneralPage; INT_PTR CALLBACK GeneralPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/base/applications/msconfig/srvpage.h b/base/applications/msconfig/srvpage.h index 89c8f3e6112..db51a1b2258 100644 --- a/base/applications/msconfig/srvpage.h +++ b/base/applications/msconfig/srvpage.h @@ -1,4 +1,9 @@ +#ifndef _SVRPAGE_H_ +#define _SVRPAGE_H_ + extern HWND hServicesPage; extern HWND hServicesListCtrl; INT_PTR CALLBACK ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/base/applications/msconfig/startuppage.h b/base/applications/msconfig/startuppage.h index 9ac644081f0..a016fb320fb 100644 --- a/base/applications/msconfig/startuppage.h +++ b/base/applications/msconfig/startuppage.h @@ -1,4 +1,9 @@ +#ifndef _STARTUPPAGE_H_ +#define _STARTUPPAGE_H_ + extern HWND hStartupPage; extern HWND hStartupPageListCtrl; INT_PTR CALLBACK StartupPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/base/applications/msconfig/systempage.h b/base/applications/msconfig/systempage.h index d928c77389c..1aa9dcafe8b 100644 --- a/base/applications/msconfig/systempage.h +++ b/base/applications/msconfig/systempage.h @@ -1,3 +1,8 @@ +#ifndef _SYSTEMPAGE_H_ +#define _SYSTEMPAGE_H_ + extern HWND hSystemPage; INT_PTR CALLBACK SystemPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/base/applications/msconfig/toolspage.h b/base/applications/msconfig/toolspage.h index daa938fec80..4ec159358bf 100644 --- a/base/applications/msconfig/toolspage.h +++ b/base/applications/msconfig/toolspage.h @@ -1,5 +1,9 @@ +#ifndef _TOOLSPAGE_H_ +#define _TOOLSPAGE_H_ + extern HWND hToolsPage; extern HWND hToolsListCtrl; INT_PTR CALLBACK ToolsPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +#endif diff --git a/base/applications/mscutils/eventvwr/eventvwr.c b/base/applications/mscutils/eventvwr/eventvwr.c index dbe44a8b913..011c0ec5da6 100644 --- a/base/applications/mscutils/eventvwr/eventvwr.c +++ b/base/applications/mscutils/eventvwr/eventvwr.c @@ -506,7 +506,6 @@ QueryEventMessages(LPWSTR lpMachineName, DWORD dwRead, dwNeeded, dwThisRecord, dwTotalRecords = 0, dwCurrentRecord = 1, dwRecordsToRead = 0, dwFlags; LPWSTR lpSourceName; LPWSTR lpComputerName; - LPWSTR lpEventStr; LPWSTR lpData; BOOL bResult = TRUE; /* Read succeeded. */ @@ -609,9 +608,6 @@ QueryEventMessages(LPWSTR lpMachineName, // This ist the data section of the current event lpData = (LPWSTR)((LPBYTE)pevlr + pevlr->DataOffset); - // This is the text of the current event - lpEventStr = (LPWSTR)((LPBYTE)pevlr + pevlr->StringOffset); - // Compute the event type EventTimeToSystemTime(pevlr->TimeWritten, &time); diff --git a/base/applications/network/arp/arp.c b/base/applications/network/arp/arp.c index 539d6cf98d7..3014b5823e0 100644 --- a/base/applications/network/arp/arp.c +++ b/base/applications/network/arp/arp.c @@ -170,9 +170,7 @@ INT DisplayArpEntries(PTCHAR pszInetAddr, PTCHAR pszIfAddr) ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); - iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if (GetIpNetTable(pIpNetTable, &Size, TRUE) != NO_ERROR) { _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); DoFormatMessage(); @@ -201,9 +199,7 @@ INT DisplayArpEntries(PTCHAR pszInetAddr, PTCHAR pszIfAddr) ZeroMemory(pIpAddrTable, sizeof(*pIpAddrTable)); - iRet = GetIpAddrTable(pIpAddrTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if ((iRet = GetIpAddrTable(pIpAddrTable, &Size, TRUE)) != NO_ERROR) { _tprintf(_T("GetIpAddrTable failed: %d\n"), iRet); DoFormatMessage(); @@ -272,7 +268,7 @@ INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) PMIB_IPNETTABLE pIpNetTable = NULL; DWORD dwIpAddr = 0; ULONG Size = 0; - INT iRet, i, val, c; + INT i, val, c; /* error checking */ @@ -320,9 +316,7 @@ INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); - iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if (GetIpNetTable(pIpNetTable, &Size, TRUE) != NO_ERROR) { _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); DoFormatMessage(); @@ -382,7 +376,7 @@ INT Addhost(PTCHAR pszInetAddr, PTCHAR pszEthAddr, PTCHAR pszIfAddr) /* Add the ARP entry */ - if ((iRet = SetIpNetEntry(pAddHost)) != NO_ERROR) + if (SetIpNetEntry(pAddHost) != NO_ERROR) { DoFormatMessage(); goto cleanup; @@ -415,7 +409,6 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) PMIB_IPNETTABLE pIpNetTable = NULL; ULONG Size = 0; DWORD dwIpAddr = 0; - INT iRet; BOOL bFlushTable = FALSE; /* error checking */ @@ -449,9 +442,7 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) ZeroMemory(pIpNetTable, sizeof(*pIpNetTable)); - iRet = GetIpNetTable(pIpNetTable, &Size, TRUE); - - if (iRet != NO_ERROR) + if (GetIpNetTable(pIpNetTable, &Size, TRUE) != NO_ERROR) { _tprintf(_T("failed to allocate memory for GetIpNetTable\n")); DoFormatMessage(); @@ -485,7 +476,7 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) if (bFlushTable == TRUE) { /* delete arp cache */ - if ((iRet = FlushIpNetTable(pDelHost->dwIndex)) != NO_ERROR) + if (FlushIpNetTable(pDelHost->dwIndex) != NO_ERROR) { DoFormatMessage(); goto cleanup; @@ -501,7 +492,7 @@ INT Deletehost(PTCHAR pszInetAddr, PTCHAR pszIfAddr) pDelHost->dwAddr = dwIpAddr; /* Add the ARP entry */ - if ((iRet = DeleteIpNetEntry(pDelHost)) != NO_ERROR) + if (DeleteIpNetEntry(pDelHost) != NO_ERROR) { DoFormatMessage(); goto cleanup; diff --git a/base/applications/network/ftp/fake.c b/base/applications/network/ftp/fake.c index f8d0c8cdadf..a00f30560be 100644 --- a/base/applications/network/ftp/fake.c +++ b/base/applications/network/ftp/fake.c @@ -29,10 +29,10 @@ int checkRecv(SOCKET s) void blkfree(char **av0) { - register char **av = av0; + register char **av = av0; - while (*av) - free(*av++); + while (*av) + free(*av++); } char **glob(register char *v) @@ -52,16 +52,16 @@ int herror(char *string) #if 0 int gettimeofday(struct timeval *timenow, - struct timezone *zone) + struct timezone *zone) { - time_t t; + time_t t; - t = clock(); + t = clock(); - timenow->tv_usec = t; - timenow->tv_sec = t / CLK_TCK; + timenow->tv_usec = t; + timenow->tv_sec = t / CLK_TCK; - return 0; + return 0; } int fgetcSocket(int s) @@ -100,13 +100,13 @@ int fgetcSocket(int s) total = recv(s, buffer, sizeof(buffer), 0); if (total == SOCKET_ERROR) - { - total = 0; - return ERROR; - } + { + total = 0; + return ERROR; + } if (total == 0) - return EOF; + return EOF; } return buffer[index++]; } @@ -142,29 +142,29 @@ int fputcSocket(int s, char putChar) buffer[1] = '\0'; if(SOCKET_ERROR==send(s, buffer, 1, 0)) { - int iret=WSAGetLastError (); - fprintf(stdout,"fputcSocket: %d\n",iret); - return 0; + int iret=WSAGetLastError (); + fprintf(stdout,"fputcSocket: %d\n",iret); + return 0; } else { - return putChar; + return putChar; } } int fputSocket(int s, char *buffer, int len) { - int iret; - while(len) { - if(SOCKET_ERROR==(iret=send(s, buffer, len, 0))) - { - iret=WSAGetLastError (); - fprintf(stdout,"fputcSocket: %d\n",iret); - return 0; - } - else { - return len-=iret; - } - } - return 0; + int iret; + while(len) { + if(SOCKET_ERROR==(iret=send(s, buffer, len, 0))) + { + iret=WSAGetLastError (); + fprintf(stdout,"fputcSocket: %d\n",iret); + return 0; + } + else { + return len-=iret; + } + } + return 0; } char *fgetsSocket(int s, char *string) @@ -180,31 +180,31 @@ char *fgetsSocket(int s, char *string) if (count == SOCKET_ERROR) { - printf("Error in fgetssocket"); - return NULL; + printf("Error in fgetssocket"); + return NULL; } if (count == 1) { - string[i] = buffer[0]; + string[i] = buffer[0]; - if (i == MAX_ASCII - 3) - { - count = 0; - string[++i] = '\n'; - string[++i] = '\0'; - } + if (i == MAX_ASCII - 3) + { + count = 0; + string[++i] = '\n'; + string[++i] = '\0'; + } } else { - if (i == 0) - return NULL; - else - { - string[i] = '\n'; - string[i + 1] = '\0'; // This is risky - return string; - } + if (i == 0) + return NULL; + else + { + string[i] = '\n'; + string[i + 1] = '\0'; // This is risky + return string; + } } @@ -250,44 +250,44 @@ char *getpass (const char * prompt) int rc; if (istty) - { - if (GetConsoleMode (in, &old_flags)) - SetConsoleMode (in, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); - else - istty = 0; - } + { + if (GetConsoleMode (in, &old_flags)) + SetConsoleMode (in, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); + else + istty = 0; + } /* Need to read line one byte at time to avoid blocking, if not a tty, so always do it this way. */ count = 0; while (1) - { - DWORD dummy; - char one_char; + { + DWORD dummy; + char one_char; - rc = ReadFile (in, &one_char, 1, &dummy, NULL); - if (rc == 0) - break; - if (one_char == '\r') - { - /* CR is always followed by LF if reading from tty. */ - if (istty) - continue; - else - break; - } - if (one_char == '\n') - break; - /* Silently truncate password string if overly long. */ - if (count < sizeof (input) - 1) - input[count++] = one_char; - } + rc = ReadFile (in, &one_char, 1, &dummy, NULL); + if (rc == 0) + break; + if (one_char == '\r') + { + /* CR is always followed by LF if reading from tty. */ + if (istty) + continue; + else + break; + } + if (one_char == '\n') + break; + /* Silently truncate password string if overly long. */ + if (count < sizeof (input) - 1) + input[count++] = one_char; + } input[count] = '\0'; WriteFile (err, "\r\n", 2, &count, NULL); if (istty) - SetConsoleMode (in, old_flags); + SetConsoleMode (in, old_flags); if (rc) - return input; + return input; } return NULL; diff --git a/base/applications/network/ftp/ftp.c b/base/applications/network/ftp/ftp.c index 2b09522fb51..5fdc81ce9fa 100644 --- a/base/applications/network/ftp/ftp.c +++ b/base/applications/network/ftp/ftp.c @@ -345,7 +345,7 @@ getreply(expecteof) cp = reply_string; while ((c = fgetcSocket(cin)) != '\n') { if (c == IAC) { /* handle telnet commands */ - switch (c = fgetcSocket(cin)) { + switch (fgetcSocket(cin)) { case WILL: case WONT: c = fgetcSocket(cin); @@ -745,7 +745,7 @@ void recvrequest(const char *cmd, const char *local, const char *remote, const c long bytes = 0, hashbytes = HASHBYTES; // struct fd_set mask; - register int c, d; + register int c; struct timeval start, stop; // struct stat st; @@ -781,6 +781,7 @@ null();// (void) signal(SIGINT, oldintr); null();// oldintr = signal(SIGINT, abortrecv); if (strcmp(local, "-") && *local != '|') { #ifndef _WIN32 + register int d; // This whole thing is a problem... access Won't work on non-existent files if (access(local, 2) < 0) { char *dir = rindex(local, '/'); @@ -919,7 +920,7 @@ null();// oldintp = signal(SIGPIPE, SIG_IGN); (*closefunc)(fout); return; } - errno = d = 0; + errno = 0; // while ((c = recv(din, buf, bufsize, 1)) > 0) { // if ((d = write(fileno(fout), buf, c)) != c) // if ((d = write(fileno(fout), buf, c)) != c) @@ -1106,10 +1107,10 @@ null();// (void) signal(SIGINT,oldintr); lostpeer(); } if (din && FD_ISSET(din, &mask)) { - while ((c = recv(din, buf, bufsize, 0)) > 0) + while (recv(din, buf, bufsize, 0) > 0) ; } - if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */ + if (getreply(0) == ERROR && code == 552) { /* needed for nic style abort */ if (data >= 0) { (void) close(data); data = -1; diff --git a/base/applications/network/ftp/ftp.rbuild b/base/applications/network/ftp/ftp.rbuild index fce05853523..60f7ea5c659 100644 --- a/base/applications/network/ftp/ftp.rbuild +++ b/base/applications/network/ftp/ftp.rbuild @@ -4,6 +4,17 @@ . + + _chdir + _getcwd + _mktemp + _unlink + _close + _fileno + _read + _write + _lseek + ws2_32 iphlpapi oldnames diff --git a/base/applications/network/nslookup/nslookup.c b/base/applications/network/nslookup/nslookup.c index 993ab04a650..3e7ce484fd9 100644 --- a/base/applications/network/nslookup/nslookup.c +++ b/base/applications/network/nslookup/nslookup.c @@ -90,11 +90,7 @@ BOOL PerformInternalLookup( PCHAR pAddr, PCHAR pResult ) BOOL bOk = FALSE; /* Makes things easier when parsing the response packet. */ - UCHAR Header1, Header2; USHORT NumQuestions; - USHORT NumAnswers; - USHORT NumAuthority; - USHORT NumAdditional; USHORT Type; if( (strlen( pAddr ) + 1) > 255 ) return FALSE; @@ -198,12 +194,7 @@ BOOL PerformInternalLookup( PCHAR pAddr, PCHAR pResult ) if( !bOk ) goto cleanup; /* Start parsing the received packet. */ - Header1 = RecBuffer[2]; - Header2 = RecBuffer[3]; NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] ); - NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] ); - NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] ); - NumAdditional = ntohs( ((PUSHORT)&RecBuffer[10])[0] ); k = 12; @@ -257,11 +248,10 @@ void PerformLookup( PCHAR pAddr ) BOOL bOk = FALSE; /* Makes things easier when parsing the response packet. */ - UCHAR Header1, Header2; + UCHAR Header2; USHORT NumQuestions; USHORT NumAnswers; USHORT NumAuthority; - USHORT NumAdditional; USHORT Type; if( (strlen( pAddr ) + 1) > 255 ) return; @@ -368,19 +358,17 @@ void PerformLookup( PCHAR pAddr ) ((PSHORT)&Buffer[i])[0] = htons( ClassNametoClassID( State.Class ) ); /* Ship off the request to the DNS server. */ - bOk = SendRequest( Buffer, + bOk = SendRequest( Buffer, BufferLength, RecBuffer, &RecBufferLength ); if( !bOk ) goto cleanup; /* Start parsing the received packet. */ - Header1 = RecBuffer[2]; Header2 = RecBuffer[3]; NumQuestions = ntohs( ((PSHORT)&RecBuffer[4])[0] ); NumAnswers = ntohs( ((PSHORT)&RecBuffer[6])[0] ); NumAuthority = ntohs( ((PUSHORT)&RecBuffer[8])[0] ); - NumAdditional = ntohs( ((PUSHORT)&RecBuffer[10])[0] ); Type = 0; /* Check the RCODE for failure. */ diff --git a/base/applications/notepad/dialog.c b/base/applications/notepad/dialog.c index 937dd5807de..d8c6adc04e6 100644 --- a/base/applications/notepad/dialog.c +++ b/base/applications/notepad/dialog.c @@ -400,7 +400,6 @@ static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wPar { TCHAR szText[128]; HWND hCombo; - OFNOTIFY *pNotify; UNREFERENCED_PARAMETER(wParam); @@ -440,15 +439,13 @@ static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wPar case WM_NOTIFY: if (((NMHDR *) lParam)->code == CDN_FILEOK) { - pNotify = (OFNOTIFY *) lParam; - hCombo = GetDlgItem(hDlg, ID_ENCODING); - if (hCombo) - Globals.iEncoding = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); + if (hCombo) + Globals.iEncoding = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); hCombo = GetDlgItem(hDlg, ID_EOLN); - if (hCombo) - Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); + if (hCombo) + Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); } break; } @@ -808,11 +805,11 @@ static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARA TCHAR szText[32]; switch(uMsg) { - case WM_INITDIALOG: + case WM_INITDIALOG: hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER); - _sntprintf(szText, SIZEOF(szText), _T("%d"), lParam); + _sntprintf(szText, SIZEOF(szText), _T("%d"), lParam); SetWindowText(hTextBox, szText); - break; + break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { @@ -823,11 +820,11 @@ static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARA EndDialog(hwndDialog, _ttoi(szText)); bResult = TRUE; } - else if (LOWORD(wParam) == IDCANCEL) - { + else if (LOWORD(wParam) == IDCANCEL) + { EndDialog(hwndDialog, 0); bResult = TRUE; - } + } } break; } @@ -862,7 +859,7 @@ VOID DIALOG_GoTo(VOID) Globals.hMainWnd, DIALOG_GoTo_DialogProc, nLine); if (nLine >= 1) - { + { for (i = 0; pszText[i] && (nLine > 1) && (i < nLength - 1); i++) { if (pszText[i] == '\n') @@ -870,8 +867,8 @@ VOID DIALOG_GoTo(VOID) } SendMessage(Globals.hEdit, EM_SETSEL, i, i); SendMessage(Globals.hEdit, EM_SCROLLCARET, 0, 0); - } - HeapFree(GetProcessHeap(), 0, pszText); + } + HeapFree(GetProcessHeap(), 0, pszText); } VOID DIALOG_StatusBarUpdateCaretPos(VOID) diff --git a/base/applications/notepad/lang/cs-CZ.rc b/base/applications/notepad/lang/cs-CZ.rc index e0be8ba66bb..d6dfcd25859 100644 --- a/base/applications/notepad/lang/cs-CZ.rc +++ b/base/applications/notepad/lang/cs-CZ.rc @@ -85,12 +85,12 @@ BEGIN END POPUP "&Nápověda" BEGIN - MENUITEM "&Obsah", CMD_HELP_CONTENTS + MENUITEM "O&bsah", CMD_HELP_CONTENTS MENUITEM "&Najít...", CMD_HELP_SEARCH - MENUITEM "&Pomoc k nápovědě", CMD_HELP_ON_HELP + MENUITEM "Pomoc k ná&povědě", CMD_HELP_ON_HELP MENUITEM SEPARATOR - MENUITEM "&O programu" CMD_ABOUT - MENUITEM "Inf&o...", CMD_ABOUT_WINE + MENUITEM "&O programu..." CMD_ABOUT + MENUITEM "In&fo...", CMD_ABOUT_WINE END END diff --git a/base/applications/paint/definitions.h b/base/applications/paint/definitions.h index 5fb041e7a4c..71ec94bf263 100644 --- a/base/applications/paint/definitions.h +++ b/base/applications/paint/definitions.h @@ -98,6 +98,24 @@ #define ID_ELLIPSE 614 #define ID_RRECT 615 +//the following 16 numbers need to be in order, increasing by 1 +#define TOOL_FREESEL 1 +#define TOOL_RECTSEL 2 +#define TOOL_RUBBER 3 +#define TOOL_FILL 4 +#define TOOL_COLOR 5 +#define TOOL_ZOOM 6 +#define TOOL_PEN 7 +#define TOOL_BRUSH 8 +#define TOOL_AIRBRUSH 9 +#define TOOL_TEXT 10 +#define TOOL_LINE 11 +#define TOOL_BEZIER 12 +#define TOOL_RECT 13 +#define TOOL_SHAPE 14 +#define TOOL_ELLIPSE 15 +#define TOOL_RRECT 16 + #define ID_ACCELERATORS 800 #define IDD_MIRRORROTATE 700 diff --git a/base/applications/paint/lang/cs-CZ.rc b/base/applications/paint/lang/cs-CZ.rc index f3a8f3d2501..da0e84b5de3 100644 --- a/base/applications/paint/lang/cs-CZ.rc +++ b/base/applications/paint/lang/cs-CZ.rc @@ -49,7 +49,7 @@ BEGIN MENUITEM SEPARATOR POPUP "Lupa" BEGIN - POPUP "User defined" + POPUP "Vlastní nastavení" BEGIN MENUITEM "12,5%", IDM_VIEWZOOM125 MENUITEM "25%", IDM_VIEWZOOM25 @@ -60,8 +60,8 @@ BEGIN MENUITEM "800%", IDM_VIEWZOOM800 END MENUITEM SEPARATOR - MENUITEM "Show grid", IDM_VIEWSHOWGRID - MENUITEM "Show miniature", IDM_VIEWSHOWMINIATURE + MENUITEM "Zobrazit mřížku", IDM_VIEWSHOWGRID + MENUITEM "Zobrazit miniaturu", IDM_VIEWSHOWMINIATURE END MENUITEM "Celá obrazovka\tCtrl+F", IDM_VIEWFULLSCREEN END @@ -86,7 +86,7 @@ BEGIN BEGIN MENUITEM "Témata nápovědy", IDM_HELPHELPTOPICS MENUITEM SEPARATOR - MENUITEM "O programu...", IDM_HELPINFO + MENUITEM "&O programu...", IDM_HELPINFO END END @@ -104,6 +104,7 @@ BEGIN "^A", IDM_EDITSELECTALL "^T", IDM_VIEWTOOLBOX "^L", IDM_VIEWCOLORPALETTE + "^G", IDM_VIEWSHOWGRID "^F", IDM_VIEWFULLSCREEN "^R", IDM_IMAGEROTATEMIRROR "^W", IDM_IMAGECHANGESIZE @@ -140,9 +141,9 @@ BEGIN LTEXT "Datum změny:", IDD_ATTRIBUTESTEXT3, 10, 5, 60, 10 LTEXT "Velikost souboru:", IDD_ATTRIBUTESTEXT4, 10, 15, 60, 10 LTEXT "Rozlišení:", IDD_ATTRIBUTESTEXT5, 10, 25, 60, 10 - LTEXT "Not available", IDD_ATTRIBUTESTEXT6, 60, 5, 90, 10 - LTEXT "Not available", IDD_ATTRIBUTESTEXT7, 60, 15, 90, 10 - LTEXT "Not available", IDD_ATTRIBUTESTEXT8, 60, 25, 90, 10 + LTEXT "Nedostupné", IDD_ATTRIBUTESTEXT6, 60, 5, 90, 10 + LTEXT "Nedostupné", IDD_ATTRIBUTESTEXT7, 60, 15, 90, 10 + LTEXT "Nedostupné", IDD_ATTRIBUTESTEXT8, 60, 25, 90, 10 GROUPBOX "Jednotka", IDD_ATTRIBUTESGROUP1, 6, 57, 139, 27 AUTORADIOBUTTON "Palce", IDD_ATTRIBUTESRB1, 12, 69, 35, 10, WS_GROUP AUTORADIOBUTTON "Centimetry", IDD_ATTRIBUTESRB2, 52, 69, 35, 10 @@ -181,7 +182,7 @@ BEGIN IDS_INFOTEXT, "ReactOS Malování je dostupné pod licencí GNU Lesser General Public License (LGPL) verze 3 (viz. www.gnu.org)" IDS_SAVEPROMPTTEXT, "Chcete uložit provedené změny v %s?" IDS_DEFAULTFILENAME, "Bez názvu.bmp" - IDS_MINIATURETITLE, "Miniature" + IDS_MINIATURETITLE, "Miniatura" IDS_TOOLTIP1, "Volný výběr" IDS_TOOLTIP2, "Výběr" IDS_TOOLTIP3, "Guma" @@ -200,6 +201,6 @@ BEGIN IDS_TOOLTIP16, "Zaoblený obdélník" IDS_OPENFILTER, "Soubory bitmap (*.bmp;*.dib)\1*.bmp;*.dib\1Všechny soubory (*.*)\1*.*\1" IDS_SAVEFILTER, "24bitová bitmapa (*.bmp;*.dib)\1*.bmp;*.dib\1" - IDS_FILESIZE, "%d bytes" - IDS_PRINTRES, "%d x %d pixels per meter" + IDS_FILESIZE, "%d bajtů" + IDS_PRINTRES, "%d x %d pixelů na metr" END diff --git a/base/applications/paint/main.c b/base/applications/paint/main.c index 904220567d1..3c77cb23999 100644 --- a/base/applications/paint/main.c +++ b/base/applications/paint/main.c @@ -50,7 +50,7 @@ short lastY; int lineWidth = 1; int shapeStyle = 0; int brushStyle = 0; -int activeTool = 7; +int activeTool = TOOL_PEN; int airBrushWidth = 5; int rubberRadius = 4; int transpBg = 0; diff --git a/base/applications/paint/mouse.c b/base/applications/paint/mouse.c index 9165291594e..d46bbe35eaf 100644 --- a/base/applications/paint/mouse.c +++ b/base/applications/paint/mouse.c @@ -67,7 +67,7 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg) lastY = y; switch (activeTool) { - case 1: + case TOOL_FREESEL: ShowWindow(hSelection, SW_HIDE); if (ptStack != NULL) HeapFree(GetProcessHeap(), 0, ptStack); @@ -76,39 +76,39 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg) ptStack[0].x = x; ptStack[0].y = y; break; - case 10: - case 11: - case 13: - case 15: - case 16: + case TOOL_TEXT: + case TOOL_LINE: + case TOOL_RECT: + case TOOL_ELLIPSE: + case TOOL_RRECT: newReversible(); break; - case 2: + case TOOL_RECTSEL: newReversible(); ShowWindow(hSelection, SW_HIDE); rectSel_src[2] = rectSel_src[3] = 0; break; - case 3: + case TOOL_RUBBER: newReversible(); Erase(hdc, x, y, x, y, bg, rubberRadius); break; - case 4: + case TOOL_FILL: newReversible(); Fill(hdc, x, y, fg); break; - case 7: + case TOOL_PEN: newReversible(); SetPixel(hdc, x, y, fg); break; - case 8: + case TOOL_BRUSH: newReversible(); Brush(hdc, x, y, x, y, fg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: newReversible(); Airbrush(hdc, x, y, fg, airBrushWidth); break; - case 12: + case TOOL_BEZIER: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP == 0) @@ -117,7 +117,7 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg) pointSP++; } break; - case 14: + case TOOL_SHAPE: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP + 1 >= 2) @@ -136,7 +136,7 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 1: + case TOOL_FREESEL: if (ptSP == 0) newReversible(); ptSP++; @@ -147,7 +147,7 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) resetToU1(); Poly(hdc, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE); break; - case 2: + case TOOL_RECTSEL: { short tempX; short tempY; @@ -161,25 +161,25 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) RectSel(hdc, startX, startY, tempX, tempY); break; } - case 3: + case TOOL_RUBBER: Erase(hdc, lastX, lastY, x, y, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, fg, 1); break; - case 8: + case TOOL_BRUSH: Brush(hdc, lastX, lastY, x, y, fg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: Airbrush(hdc, x, y, fg, airBrushWidth); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, fg, lineWidth); break; - case 12: + case TOOL_BEZIER: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -197,13 +197,13 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) break; } break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -213,13 +213,13 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg) if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, fg, bg, lineWidth, shapeStyle, FALSE); break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); @@ -236,7 +236,7 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 1: + case TOOL_FREESEL: { POINT *ptStackCopy; int i; @@ -279,6 +279,9 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) Poly(hdc, ptStack, ptSP + 1, bg, bg, 1, 2, TRUE); newReversible(); + MaskBlt(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[2], rectSel_src[3], hSelDC, 0, + 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND)); + placeSelWin(); ShowWindow(hSelection, SW_SHOW); } @@ -286,7 +289,7 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) ptStack = NULL; break; } - case 2: + case TOOL_RECTSEL: resetToU1(); if ((rectSel_src[2] != 0) && (rectSel_src[3] != 0)) { @@ -302,35 +305,38 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) rectSel_src[1] + rectSel_src[3], bgColor, bgColor, 0, TRUE); newReversible(); + BitBlt(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[2], rectSel_src[3], hSelDC, 0, + 0, SRCCOPY); + placeSelWin(); ShowWindow(hSelection, SW_SHOW); } break; - case 3: + case TOOL_RUBBER: Erase(hdc, lastX, lastY, x, y, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, fg, 1); SetPixel(hdc, x, y, fg); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, fg, lineWidth); break; - case 12: + case TOOL_BEZIER: pointSP++; if (pointSP == 4) pointSP = 0; break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -354,13 +360,13 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg) if (pointSP == 255) pointSP--; break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, fg, bg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); @@ -378,35 +384,35 @@ startPaintingR(HDC hdc, short x, short y, int fg, int bg) lastY = y; switch (activeTool) { - case 1: - case 10: - case 11: - case 13: - case 15: - case 16: + case TOOL_FREESEL: + case TOOL_TEXT: + case TOOL_LINE: + case TOOL_RECT: + case TOOL_ELLIPSE: + case TOOL_RRECT: newReversible(); break; - case 3: + case TOOL_RUBBER: newReversible(); Replace(hdc, x, y, x, y, fg, bg, rubberRadius); break; - case 4: + case TOOL_FILL: newReversible(); Fill(hdc, x, y, bg); break; - case 7: + case TOOL_PEN: newReversible(); SetPixel(hdc, x, y, bg); break; - case 8: + case TOOL_BRUSH: newReversible(); Brush(hdc, x, y, x, y, bg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: newReversible(); Airbrush(hdc, x, y, bg, airBrushWidth); break; - case 12: + case TOOL_BEZIER: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP == 0) @@ -415,7 +421,7 @@ startPaintingR(HDC hdc, short x, short y, int fg, int bg) pointSP++; } break; - case 14: + case TOOL_SHAPE: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP + 1 >= 2) @@ -434,25 +440,25 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 3: + case TOOL_RUBBER: Replace(hdc, lastX, lastY, x, y, fg, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, bg, 1); break; - case 8: + case TOOL_BRUSH: Brush(hdc, lastX, lastY, x, y, bg, brushStyle); break; - case 9: + case TOOL_AIRBRUSH: Airbrush(hdc, x, y, bg, airBrushWidth); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, bg, lineWidth); break; - case 12: + case TOOL_BEZIER: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -470,13 +476,13 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg) break; } break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -486,13 +492,13 @@ whilePaintingR(HDC hdc, short x, short y, int fg, int bg) if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, bg, fg, lineWidth, shapeStyle, FALSE); break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); @@ -509,31 +515,31 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg) { switch (activeTool) { - case 3: + case TOOL_RUBBER: Replace(hdc, lastX, lastY, x, y, fg, bg, rubberRadius); break; - case 7: + case TOOL_PEN: Line(hdc, lastX, lastY, x, y, bg, 1); SetPixel(hdc, x, y, bg); break; - case 11: + case TOOL_LINE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(startX, startY, &x, &y); Line(hdc, startX, startY, x, y, bg, lineWidth); break; - case 12: + case TOOL_BEZIER: pointSP++; if (pointSP == 4) pointSP = 0; break; - case 13: + case TOOL_RECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Rect(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 14: + case TOOL_SHAPE: resetToU1(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; @@ -557,13 +563,13 @@ endPaintingR(HDC hdc, short x, short y, int fg, int bg) if (pointSP == 255) pointSP--; break; - case 15: + case TOOL_ELLIPSE: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); Ellp(hdc, startX, startY, x, y, bg, fg, lineWidth, shapeStyle); break; - case 16: + case TOOL_RRECT: resetToU1(); if (GetAsyncKeyState(VK_SHIFT) < 0) regularize(startX, startY, &x, &y); diff --git a/base/applications/paint/toolsettings.c b/base/applications/paint/toolsettings.c index bfb2172f0bf..2e5cd67661d 100644 --- a/base/applications/paint/toolsettings.c +++ b/base/applications/paint/toolsettings.c @@ -34,13 +34,13 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DefWindowProc(hwnd, message, wParam, lParam); - DrawEdge(hdc, &rect1, BDR_SUNKENOUTER, (activeTool == 6) ? BF_RECT : BF_RECT | BF_MIDDLE); - DrawEdge(hdc, &rect2, (activeTool >= 13) ? BDR_SUNKENOUTER : 0, BF_RECT | BF_MIDDLE); + DrawEdge(hdc, &rect1, BDR_SUNKENOUTER, (activeTool == TOOL_ZOOM) ? BF_RECT : BF_RECT | BF_MIDDLE); + DrawEdge(hdc, &rect2, (activeTool >= TOOL_RECT) ? BDR_SUNKENOUTER : 0, BF_RECT | BF_MIDDLE); switch (activeTool) { - case 1: - case 2: - case 10: + case TOOL_FREESEL: + case TOOL_RECTSEL: + case TOOL_TEXT: { HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); SelectObject(hdc, GetSysColorBrush(COLOR_HIGHLIGHT)); @@ -50,7 +50,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DrawIconEx(hdc, 1, 33, hTranspIcon, 40, 30, 0, NULL, DI_NORMAL); break; } - case 3: + case TOOL_RUBBER: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -69,7 +69,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteObject(SelectObject(hdc, oldPen)); break; } - case 8: + case TOOL_BRUSH: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -82,7 +82,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GetSysColor((i == brushStyle) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT), i); break; } - case 9: + case TOOL_AIRBRUSH: { HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); SelectObject(hdc, GetSysColorBrush(COLOR_HIGHLIGHT)); @@ -112,8 +112,8 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteObject(SelectObject(hdc, oldPen)); break; } - case 11: - case 12: + case TOOL_LINE: + case TOOL_BEZIER: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -132,10 +132,10 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DeleteObject(SelectObject(hdc, oldPen)); break; } - case 13: - case 14: - case 15: - case 16: + case TOOL_RECT: + case TOOL_SHAPE: + case TOOL_ELLIPSE: + case TOOL_RRECT: { int i; HPEN oldPen = SelectObject(hdc, CreatePen(PS_NULL, 0, 0)); @@ -178,23 +178,23 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (activeTool) { - case 1: - case 2: - case 10: + case TOOL_FREESEL: + case TOOL_RECTSEL: + case TOOL_TEXT: if ((HIWORD(lParam) > 1) && (HIWORD(lParam) < 64)) { transpBg = (HIWORD(lParam) - 2) / 31; SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 3: + case TOOL_RUBBER: if ((HIWORD(lParam) > 1) && (HIWORD(lParam) < 62)) { rubberRadius = (HIWORD(lParam) - 2) / 15 + 2; SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 8: + case TOOL_BRUSH: if ((LOWORD(lParam) > 1) && (LOWORD(lParam) < 40) && (HIWORD(lParam) > 1) && (HIWORD(lParam) < 62)) { @@ -202,7 +202,7 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 9: + case TOOL_AIRBRUSH: if (HIWORD(lParam) < 62) { if (HIWORD(lParam) < 30) @@ -222,18 +222,18 @@ SettingsWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 11: - case 12: + case TOOL_LINE: + case TOOL_BEZIER: if (HIWORD(lParam) <= 62) { lineWidth = (HIWORD(lParam) - 2) / 12 + 1; SendMessage(hwnd, WM_PAINT, 0, 0); } break; - case 13: - case 14: - case 15: - case 16: + case TOOL_RECT: + case TOOL_SHAPE: + case TOOL_ELLIPSE: + case TOOL_RRECT: if (HIWORD(lParam) <= 60) { shapeStyle = (HIWORD(lParam) - 2) / 20; diff --git a/base/applications/paint/winproc.c b/base/applications/paint/winproc.c index 464b62c9842..18bbaa61a67 100644 --- a/base/applications/paint/winproc.c +++ b/base/applications/paint/winproc.c @@ -460,19 +460,19 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (activeTool) { - case 4: + case TOOL_FILL: SetCursor(hCurFill); break; - case 5: + case TOOL_COLOR: SetCursor(hCurColor); break; - case 6: + case TOOL_ZOOM: SetCursor(hCurZoom); break; - case 7: + case TOOL_PEN: SetCursor(hCurPen); break; - case 9: + case TOOL_AIRBRUSH: SetCursor(hCurAirbrush); break; default: @@ -486,7 +486,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDOWN: if (hwnd == hImageArea) { - if ((!drawing) || (activeTool == 5)) + if ((!drawing) || (activeTool == TOOL_COLOR)) { SetCapture(hImageArea); drawing = TRUE; @@ -499,7 +499,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) undo(); } SendMessage(hImageArea, WM_PAINT, 0, 0); - if ((activeTool == 6) && (zoom < 8000)) + if ((activeTool == TOOL_ZOOM) && (zoom < 8000)) zoomTo(zoom * 2, (short)LOWORD(lParam), (short)HIWORD(lParam)); } break; @@ -507,7 +507,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_RBUTTONDOWN: if (hwnd == hImageArea) { - if ((!drawing) || (activeTool == 5)) + if ((!drawing) || (activeTool == TOOL_COLOR)) { SetCapture(hImageArea); drawing = TRUE; @@ -520,7 +520,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) undo(); } SendMessage(hImageArea, WM_PAINT, 0, 0); - if ((activeTool == 6) && (zoom > 125)) + if ((activeTool == TOOL_ZOOM) && (zoom > 125)) zoomTo(zoom / 2, (short)LOWORD(lParam), (short)HIWORD(lParam)); } break; @@ -533,7 +533,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) endPaintingL(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if (activeTool == 5) + if (activeTool == TOOL_COLOR) { int tempColor = GetPixel(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom); @@ -553,7 +553,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) endPaintingR(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if (activeTool == 5) + if (activeTool == TOOL_COLOR) { int tempColor = GetPixel(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom); @@ -568,16 +568,13 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: if (hwnd == hImageArea) { - if ((!drawing) || (activeTool <= 9)) + short xNow = (short)LOWORD(lParam) * 1000 / zoom; + short yNow = (short)HIWORD(lParam) * 1000 / zoom; + if ((!drawing) || (activeTool <= TOOL_AIRBRUSH)) { TRACKMOUSEEVENT tme; - TCHAR coordStr[100]; - _stprintf(coordStr, _T("%d, %d"), (short)LOWORD(lParam) * 1000 / zoom, - (short)HIWORD(lParam) * 1000 / zoom); - SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); - - if (activeTool == 6) + if (activeTool == TOOL_ZOOM) { SendMessage(hImageArea, WM_PAINT, 0, 0); drawZoomFrame((short)LOWORD(lParam), (short)HIWORD(lParam)); @@ -588,32 +585,73 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) tme.hwndTrack = hImageArea; tme.dwHoverTime = 0; TrackMouseEvent(&tme); + + if (!drawing) + { + TCHAR coordStr[100]; + _stprintf(coordStr, _T("%d, %d"), xNow, yNow); + SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); + } } if (drawing) { + /* values displayed in statusbar */ + short xRel = xNow - startX; + short yRel = yNow - startY; + /* freesel, rectsel and text tools always show numbers limited to fit into image area */ + if ((activeTool == TOOL_FREESEL) || (activeTool == TOOL_RECTSEL) || (activeTool == TOOL_TEXT)) + { + if (xRel < 0) + xRel = (xNow < 0) ? -startX : xRel; + else if (xNow > imgXRes) + xRel = imgXRes-startX; + if (yRel < 0) + yRel = (yNow < 0) ? -startY : yRel; + else if (yNow > imgYRes) + yRel = imgYRes-startY; + } + /* rectsel and shape tools always show non-negative numbers when drawing */ + if ((activeTool == TOOL_RECTSEL) || (activeTool == TOOL_SHAPE)) + { + if (xRel < 0) + xRel = -xRel; + if (yRel < 0) + yRel = -yRel; + } + /* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */ + switch(activeTool) + { + case TOOL_RUBBER: + case TOOL_PEN: + case TOOL_BRUSH: + case TOOL_AIRBRUSH: + case TOOL_SHAPE: + { + TCHAR coordStr[100]; + _stprintf(coordStr, _T("%d, %d"), xNow, yNow); + SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); + break; + } + } if ((wParam & MK_LBUTTON) != 0) { - whilePaintingL(hDrawingDC, (short)LOWORD(lParam) * 1000 / zoom, - (short)HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); + whilePaintingL(hDrawingDC, xNow, yNow, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if ((activeTool >= 10) || (activeTool == 2)) + if ((activeTool >= TOOL_TEXT) || (activeTool == TOOL_RECTSEL) || (activeTool == TOOL_FREESEL)) { TCHAR sizeStr[100]; - _stprintf(sizeStr, _T("%d x %d"), (short)LOWORD(lParam) * 1000 / zoom - startX, - (short)HIWORD(lParam) * 1000 / zoom - startY); + _stprintf(sizeStr, _T("%d x %d"), xRel, yRel); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); } } if ((wParam & MK_RBUTTON) != 0) { - whilePaintingR(hDrawingDC, (short)LOWORD(lParam) * 1000 / zoom, - (short)HIWORD(lParam) * 1000 / zoom, fgColor, bgColor); + whilePaintingR(hDrawingDC, xNow, yNow, fgColor, bgColor); SendMessage(hImageArea, WM_PAINT, 0, 0); - if (activeTool >= 10) + if (activeTool >= TOOL_TEXT) { TCHAR sizeStr[100]; - _stprintf(sizeStr, _T("%d x %d"), (short)LOWORD(lParam) * 1000 / zoom - startX, - (short)HIWORD(lParam) * 1000 / zoom - startY); + _stprintf(sizeStr, _T("%d x %d"), xRel, yRel); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); } } @@ -623,7 +661,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSELEAVE: SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T("")); - if (activeTool == 6) + if (activeTool == TOOL_ZOOM) SendMessage(hImageArea, WM_PAINT, 0, 0); break; @@ -747,7 +785,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* remove selection window and already painted content using undo(), paint Rect for rectangular selections and nothing for freeform selections */ undo(); - if (activeTool == 2) + if (activeTool == TOOL_RECTSEL) { newReversible(); Rect(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2] + rectSel_dest[0], @@ -756,7 +794,7 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; } case IDM_EDITSELECTALL: - if (activeTool == 2) + if (activeTool == TOOL_RECTSEL) { startPaintingL(hDrawingDC, 0, 0, fgColor, bgColor); whilePaintingL(hDrawingDC, imgXRes, imgYRes, fgColor, bgColor); diff --git a/base/applications/rapps/lang/de-DE.rc b/base/applications/rapps/lang/de-DE.rc index b48f0ea2229..ea4dbc80de6 100644 --- a/base/applications/rapps/lang/de-DE.rc +++ b/base/applications/rapps/lang/de-DE.rc @@ -185,7 +185,7 @@ BEGIN IDS_UPDATES "Aktualisierungen" IDS_APPLICATIONS "Anwendungen" IDS_CHOOSE_FOLDER_TEXT "Wählen Sie ein Verzeichnis aus, das zum Herunterladen verwendet werden soll:" - IDS_CHOOSE_FOLDER_ERROR "Sie haben ein nicht existentes Verzeichnis angegeben!" + IDS_CHOOSE_FOLDER_ERROR "Sie haben ein nicht existierendes Verzeichnis angegeben! Neu anlegen?" IDS_USER_NOT_ADMIN "Sie müssen als Administrator angemeldet sein, um den Anwendungsmanager zu starten!" IDS_APP_REG_REMOVE "Sind Sie sich sicher, dass Sie die Daten dieses Programms aus der Registry entfernen möchten?" IDS_INFORMATION "Informationen" diff --git a/base/applications/rapps/lang/en-US.rc b/base/applications/rapps/lang/en-US.rc index f8d018923dc..677ca86c13b 100644 --- a/base/applications/rapps/lang/en-US.rc +++ b/base/applications/rapps/lang/en-US.rc @@ -185,7 +185,7 @@ BEGIN IDS_UPDATES "Updates" IDS_APPLICATIONS "Applications" IDS_CHOOSE_FOLDER_TEXT "Choose a folder which will store Downloads:" - IDS_CHOOSE_FOLDER_ERROR "The folder you have specified does not exist." + IDS_CHOOSE_FOLDER_ERROR "The folder you have specified does not exist. Create it?" IDS_USER_NOT_ADMIN "You must be an administrator to start ""ReactOS Applications Manager""!" IDS_APP_REG_REMOVE "Are you sure you want to delete the data on the installed program from the registry?" IDS_INFORMATION "Information" diff --git a/base/applications/rapps/lang/it-IT.rc b/base/applications/rapps/lang/it-IT.rc index 44fcfab4a8a..35366716d7d 100644 --- a/base/applications/rapps/lang/it-IT.rc +++ b/base/applications/rapps/lang/it-IT.rc @@ -156,7 +156,7 @@ BEGIN IDS_CAT_DEVEL "Sviluppo" IDS_CAT_DRIVERS "Drivers" IDS_CAT_EDU "Edutainment" - IDS_CAT_ENGINEER "Engineering" + IDS_CAT_ENGINEER "Scienze" IDS_CAT_FINANCE "Finanza" IDS_CAT_GAMES "Giochi e divertimento" IDS_CAT_GRAPHICS "Graphica" @@ -174,18 +174,18 @@ BEGIN IDS_APPTITLE "ReactOS Applications Manager" IDS_SEARCH_TEXT "Cerca..." IDS_INSTALL "Installa" - IDS_UNINSTALL "Disinstall" + IDS_UNINSTALL "Disinstalla" IDS_MODIFY "Modifica" IDS_APPS_COUNT "Numero applicazioni: %d" IDS_WELCOME_TITLE "Benvenuto!\n\n" IDS_WELCOME_TEXT "Scegliere una categoria a sinistra, poi scegliere una applicazione da installare o disinstallare.\nReactOS Web Site: " IDS_WELCOME_URL "http://www.reactos.org" IDS_INSTALLED "Installato" - IDS_AVAILABLEFORINST "Disponibile" + IDS_AVAILABLEFORINST "Disponibile per l'installazione" IDS_UPDATES "Aggiornamenti" IDS_APPLICATIONS "Applicazioni" IDS_CHOOSE_FOLDER_TEXT "Scegliere una cartella dove scaricare le applicazioni:" - IDS_CHOOSE_FOLDER_ERROR "La cartella indicata non esiste." + IDS_CHOOSE_FOLDER_ERROR "La cartella indicata non esiste. Vuoi crearla?" IDS_USER_NOT_ADMIN "Dovete essere Amministratore per avviare ""ReactOS Applications Manager""!" IDS_APP_REG_REMOVE "Sicuro di voler cancellare dal registry i dati sui programmi installati?" IDS_INFORMATION "Informazioni" diff --git a/base/applications/rapps/lang/pl-PL.rc b/base/applications/rapps/lang/pl-PL.rc index 60fd20b7530..5b68948a7e7 100644 --- a/base/applications/rapps/lang/pl-PL.rc +++ b/base/applications/rapps/lang/pl-PL.rc @@ -187,7 +187,7 @@ BEGIN IDS_UPDATES "Uaktualnienia" IDS_APPLICATIONS "Aplikacje" IDS_CHOOSE_FOLDER_TEXT "Wybierz katalog w którym będa zapisywane pobrane programy:" - IDS_CHOOSE_FOLDER_ERROR "Wybrałeś nieistniejący katalog!" + IDS_CHOOSE_FOLDER_ERROR "Wybrałeś nieistniejący katalog! Czy chcesz utworzyć nowy?" IDS_USER_NOT_ADMIN "Musisz mieć uprawnienia administratora aby uruchomić ""ReactOS Applications Manager""!" IDS_APP_REG_REMOVE "Czy na pewno chcesz usunąć wpis tego programu z rejestru?" IDS_INFORMATION "Informacja" diff --git a/base/applications/rapps/rapps/abiword28x.txt b/base/applications/rapps/rapps/abiword28x.txt new file mode 100644 index 00000000000..0e4001cd493 --- /dev/null +++ b/base/applications/rapps/rapps/abiword28x.txt @@ -0,0 +1,21 @@ +; UTF-8 + +[Section] +Name = AbiWord +Version = 2.8.5 +Licence = GPL +Description = Word processor. +Size = 7.9MB +Category = 6 +URLSite = http://www.abisource.com/ +URLDownload = http://www.abisource.com/downloads/abiword/2.8.5/Windows/abiword-setup-2.8.5.exe +CDPath = none + +[Section.0407] +Description = Textverarbeitung. + +[Section.040a] +Description = Procesador de textos. + +[Section.0415] +Description = Edytor tekstu. diff --git a/base/applications/rapps/rapps/firefox2.txt b/base/applications/rapps/rapps/firefox2.txt index 3cf7dc27921..e0b62661193 100644 --- a/base/applications/rapps/rapps/firefox2.txt +++ b/base/applications/rapps/rapps/firefox2.txt @@ -8,35 +8,20 @@ Description = The most popular and one of the best free Web Browsers out there. Size = 5.8M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/en-US/Firefox%20Setup%202.0.0.20.exe +URLDownload = http://svn.reactos.org/packages/Firefox%20Setup%202.0.0.20.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. -Size = 5.5M -URLSite = http://www.mozilla-europe.org/de/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/de/Firefox%20Setup%202.0.0.20.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. -Size = 5.6M -URLSite = http://www.mozilla-europe.org/es/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/es-ES/Firefox%20Setup%202.0.0.20.exe [Section.0414] Description = Mest populære og best ogsĂĄ gratis nettleserene der ute. -Size = 5.6M -URLSite = http://www.mozilla-europe.org/no/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/nb-NO/Firefox%20Setup%202.0.0.20.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. -Size = 6.3M -URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/pl/Firefox%20Setup%202.0.0.20.exe [Section.0419] Description = Один из Ńамых попŃлярных и Đ»ŃчŃих беŃплатных браŃзеров. -Size = 6.4M -URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = http://194.71.11.70/pub/www/clients/mozilla.org/firefox/releases/2.0.0.20/win32/ru/Firefox%20Setup%202.0.0.20.exe diff --git a/base/applications/rapps/rapps/firefox36.txt b/base/applications/rapps/rapps/firefox36.txt new file mode 100644 index 00000000000..f605dc063be --- /dev/null +++ b/base/applications/rapps/rapps/firefox36.txt @@ -0,0 +1,42 @@ +; UTF-8 + +[Section] +Name = Mozilla Firefox 3.6 +Version = 3.6.3 +Licence = MPL/GPL/LGPL +Description = The most popular and one of the best free Web Browsers out there. +Size = 8.0M +Category = 5 +URLSite = http://www.mozilla.com/en-US/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/en-US/Firefox%20Setup%203.6.3.exe +CDPath = none + +[Section.0407] +Description = Der populärste und einer der besten freien Webbrowser. +Size = 7.8M +URLSite = http://www.mozilla-europe.org/de/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/de/Firefox%20Setup%203.6.3.exe + +[Section.040a] +Description = El más popular y uno de los mejores navegadores web gratuitos que hay. +Size = 7.8M +URLSite = http://www.mozilla-europe.org/es/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/es-ES/Firefox%20Setup%203.6.3.exe + +[Section.0414] +Description = Mest populære og best ogsĂĄ gratis nettleserene der ute. +Size = 7.8M +URLSite = http://www.mozilla-europe.org/no/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/nb-NO/Firefox%20Setup%203.6.3.exe + +[Section.0415] +Description = Najpopularniejsza i jedna z najlepszych darmowych przeglÄ…darek internetowych. +Size = 8.6M +URLSite = http://www.mozilla-europe.org/pl/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/pl/Firefox%20Setup%203.6.3.exe + +[Section.0419] +Description = Один из Ńамых попŃлярных и Đ»ŃчŃих беŃплатных браŃзеров. +Size = 8.2M +URLSite = http://www.mozilla-europe.org/ru/ +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/ru/Firefox%20Setup%203.6.3.exe diff --git a/base/applications/rapps/rapps/mirandaim.txt b/base/applications/rapps/rapps/mirandaim.txt index aadc724e326..5845bf7eb97 100644 --- a/base/applications/rapps/rapps/mirandaim.txt +++ b/base/applications/rapps/rapps/mirandaim.txt @@ -2,13 +2,13 @@ [Section] Name = Miranda IM -Version = 0.8.22 +Version = 0.8.24 Licence = GPL Description = Open source multiprotocol instant messaging application - May not work completely. -Size = 1.6MB +Size = 1.7MB Category = 5 URLSite = http://www.miranda-im.org/ -URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.22-unicode.exe +URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.24-unicode.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/openoffice3.0.txt b/base/applications/rapps/rapps/openoffice3.0.txt index b9ee71bd025..9ae02ef5d4e 100644 --- a/base/applications/rapps/rapps/openoffice3.0.txt +++ b/base/applications/rapps/rapps/openoffice3.0.txt @@ -2,30 +2,29 @@ [Section] Name = OpenOffice 3.0 -Version = 3.2.0 +Version = 3.2.1 Licence = LGPL Description = THE Open Source Office Suite. -Size = 135.4MB +Size = 134.0MB Category = 6 URLSite = http://www.openoffice.org/ -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/stable/3.2.0/OOo_3.2.0_Win32Intel_install_en-US.exe +URLDownload = http://ftp3.gwdg.de/pub/openoffice/stable/3.2.1/OOo_3.2.1_Win_x86_install_en-US.exe CDPath = none [Section.0407] Description = DIE Open Source Office Suite. URLSite = http://de.openoffice.org/ -Size = 145.8MB -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/de/3.2.0/OOo_3.2.0_Win32Intel_install_de.exe +Size = 144.0MB +URLDownload = http://ftp3.gwdg.de/pub/openoffice/localized/de/3.2.1/OOo_3.2.1_Win_x86_install_de.exe [Section.040a] Description = La suite de ofimática de cĂłdigo abierto. URLSite = http://es.openoffice.org/ -Version = 3.1.0 -Size = 119.4MB -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/es/3.2.0/OOo_3.2.0_Win32Intel_install_es.exe +Size = 144.0MB +URLDownload = http://ftp3.gwdg.de/pub/openoffice/localized/es/3.2.1/OOo_3.2.1_Win_x86_install-wJRE_es.exe [Section.0415] Description = Otwarty pakiet biurowy. URLSite = http://pl.openoffice.org/ -Size = 133.2MB -URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/pl/3.2.0/OOo_3.2.0_Win32Intel_install_pl.exe +Size = 130.0MB +URLDownload = http://ftp3.gwdg.de/pub/openoffice/localized/pl/3.2.1/OOo_3.2.1_Win_x86_install_pl.exe diff --git a/base/applications/rapps/rapps/opera9.txt b/base/applications/rapps/rapps/opera9.txt new file mode 100644 index 00000000000..e951d00bc2a --- /dev/null +++ b/base/applications/rapps/rapps/opera9.txt @@ -0,0 +1,24 @@ +; UTF-8 + +[Section] +Name = Opera +Version = 9.64 +Licence = Freeware +Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client. +Size = 7.2M +Category = 5 +URLSite = http://www.opera.com/ +URLDownload = http://get4.opera.com/pub/opera/win/964/int/Opera_964_int_Setup.exe +CDPath = none + +[Section.0407] +Description = Der populäre Opera Browser mit vielen fortschrittlichen Eigenschaften, enthält einen Mail und BitTorrent Client. + +[Section.040a] +Description = Popular navegador web con muchas caracterĂ­sticas avanzadas e incluye un cliente de correo y BitTorrent. + +[Section.0415] +Description = Popularna przeglÄ…darka internetowa z wieloma zaawansowanymi funkcjami, zawierajÄ…ca klientĂłw: poczty oraz BitTorrent. + +[Section.0419] +Description = ПопŃлярный браŃзер ŃĐľ многими дополнительными возможноŃтями, включающий клиентов почты и BitTorrent. diff --git a/base/applications/rapps/rapps/rosbe.txt b/base/applications/rapps/rapps/rosbe.txt index 384df84563a..a019299b9d1 100644 --- a/base/applications/rapps/rapps/rosbe.txt +++ b/base/applications/rapps/rapps/rosbe.txt @@ -2,13 +2,13 @@ [Section] Name = ReactOS Build Environment -Version = 1.5.1 +Version = 1.5.1.1 Licence = GPL Description = Allows you to build the ReactOS Source. For more instructions see ReactOS wiki. -Size = 13.5MB +Size = 13.8MB Category = 7 -URLSite = http://reactos.org/wiki/Build_Environment/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/reactos/RosBE-1.5.1.exe +URLSite = http://reactos.org/wiki/Build_Environment +URLDownload = http://ovh.dl.sourceforge.net/sourceforge/reactos/RosBE-1.5.1.1.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/scite.txt b/base/applications/rapps/rapps/scite.txt index c32df9cd195..2da34b49e95 100644 --- a/base/applications/rapps/rapps/scite.txt +++ b/base/applications/rapps/rapps/scite.txt @@ -2,13 +2,13 @@ [Section] Name = SciTE -Version = 2.11 +Version = 2.12 Licence = Freeware Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs. Size = 0.6M Category = 7 URLSite = http://www.scintilla.org/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc211.exe +URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc212.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/settingsdlg.c b/base/applications/rapps/settingsdlg.c index 3764f0140bb..77034c51f5a 100644 --- a/base/applications/rapps/settingsdlg.c +++ b/base/applications/rapps/settingsdlg.c @@ -115,7 +115,14 @@ SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) IDS_CHOOSE_FOLDER_ERROR, szMsgText, sizeof(szMsgText) / sizeof(WCHAR)); - MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR); + if (MessageBoxW(hDlg, szMsgText, NULL, MB_YESNO) == IDYES) + { + if (CreateDirectoryW(szDir, NULL)) + { + EndDialog(hDlg, LOWORD(wParam)); + } + } + SetFocus(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT)); break; } diff --git a/base/applications/regedit/edit.c b/base/applications/regedit/edit.c index ca4d5b3ac8f..6ed32b974bb 100644 --- a/base/applications/regedit/edit.c +++ b/base/applications/regedit/edit.c @@ -276,7 +276,6 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP { WNDPROC oldproc; HWND hwndValue; - int len; TCHAR ValueString[32]; LPTSTR Remainder; DWORD Base; @@ -319,7 +318,7 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP dwordEditMode = EDIT_MODE_HEX; if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) { - if ((len = GetWindowTextLength(hwndValue))) + if (GetWindowTextLength(hwndValue)) { if (GetWindowText(hwndValue, ValueString, 32)) { @@ -339,7 +338,7 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP dwordEditMode = EDIT_MODE_DEC; if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) { - if ((len = GetWindowTextLength(hwndValue))) + if (GetWindowTextLength(hwndValue)) { if (GetWindowText(hwndValue, ValueString, 32)) { @@ -356,7 +355,7 @@ INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP case IDOK: if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) { - if ((len = GetWindowTextLength(hwndValue))) + if (GetWindowTextLength(hwndValue)) { if (!GetWindowText(hwndValue, ValueString, 32)) { diff --git a/base/applications/regedit/find.c b/base/applications/regedit/find.c index e20d01684f8..e3bb26ee404 100644 --- a/base/applications/regedit/find.c +++ b/base/applications/regedit/find.c @@ -684,7 +684,7 @@ BOOL FindNext(HWND hWnd) free(pszFoundValueName); SetFocus(g_pChildWnd->hListWnd); } - return fSuccess; + return fSuccess || s_bAbort; } static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -807,7 +807,7 @@ void FindDialog(HWND hWnd) if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND), hWnd, FindDialogProc, 0) != 0) { - if (FindNext(hWnd) == FALSE) + if (!FindNext(hWnd)) { TCHAR msg[128], caption[128]; diff --git a/base/applications/regedit/lang/cs-CZ.rc b/base/applications/regedit/lang/cs-CZ.rc index 8f36dadaf0d..b412af4c186 100644 --- a/base/applications/regedit/lang/cs-CZ.rc +++ b/base/applications/regedit/lang/cs-CZ.rc @@ -54,8 +54,8 @@ BEGIN MENUITEM "&Exportovat do souboru registru...", ID_REGISTRY_EXPORTREGISTRYFILE MENUITEM SEPARATOR - MENUITEM "Load Hive...", ID_REGISTRY_LOADHIVE, GRAYED - MENUITEM "Unload Hive...", ID_REGISTRY_UNLOADHIVE, GRAYED + MENUITEM "Načíst strom registru...", ID_REGISTRY_LOADHIVE, GRAYED + MENUITEM "Uvolnit strom registru...", ID_REGISTRY_UNLOADHIVE, GRAYED MENUITEM SEPARATOR MENUITEM "&Připojit síťový registr...", ID_REGISTRY_CONNECTNETWORKREGISTRY @@ -79,19 +79,19 @@ BEGIN MENUITEM "&Řetězec", ID_EDIT_NEW_STRINGVALUE MENUITEM "&Binární hodnota", ID_EDIT_NEW_BINARYVALUE MENUITEM "&Hodnota DWORD", ID_EDIT_NEW_DWORDVALUE - MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE - MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + MENUITEM "&Víceřetězcová hodnota", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Rozšiřitelná řetězcová hodnota", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END MENUITEM SEPARATOR - MENUITEM "&Oprávnění...", ID_EDIT_PERMISSIONS + MENUITEM "Oprá&vnění...", ID_EDIT_PERMISSIONS MENUITEM SEPARATOR MENUITEM "&Odstranit\tDel", ID_EDIT_DELETE MENUITEM "&Přejmenovat", ID_EDIT_RENAME MENUITEM SEPARATOR MENUITEM "Z&kopírovat název klíče", ID_EDIT_COPYKEYNAME MENUITEM SEPARATOR - MENUITEM "&Hledat\tCtrl+F", ID_EDIT_FIND - MENUITEM "Hledat &další\tF3", ID_EDIT_FINDNEXT + MENUITEM "&Najít\tCtrl+F", ID_EDIT_FIND + MENUITEM "Najít &další\tF3", ID_EDIT_FINDNEXT END POPUP "&Zobrazit" BEGIN @@ -103,10 +103,8 @@ BEGIN END POPUP "&Oblíbené" BEGIN - MENUITEM "&Přidat k oblíbeným", ID_FAVOURITES_ADDTOFAVOURITES - , GRAYED - MENUITEM "&Odebrat z oblíbených", ID_FAVOURITES_REMOVEFAVOURITE - , GRAYED + MENUITEM "&Přidat k oblíbeným", ID_FAVOURITES_ADDTOFAVOURITES, GRAYED + MENUITEM "&Odebrat z oblíbených", ID_FAVOURITES_REMOVEFAVOURITE, GRAYED END POPUP "&Nápověda" BEGIN @@ -135,32 +133,32 @@ BEGIN MENUITEM "&Řetězec", ID_EDIT_NEW_STRINGVALUE MENUITEM "&Binární hodnota", ID_EDIT_NEW_BINARYVALUE MENUITEM "&Hodnota DWORD", ID_EDIT_NEW_DWORDVALUE - MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE - MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + MENUITEM "&Víceřetězcová hodnota", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Rozšiřitelná řetězcová hodnota", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END END POPUP "" BEGIN - MENUITEM "Expand/Collapse", ID_TREE_EXPANDBRANCH - POPUP "&New" + MENUITEM "Rozbalit/Sbalit", ID_TREE_EXPANDBRANCH + POPUP "&Nový" BEGIN - MENUITEM "&Key", ID_EDIT_NEW_KEY + MENUITEM "&Klíč", ID_EDIT_NEW_KEY MENUITEM SEPARATOR - MENUITEM "&String Value", ID_EDIT_NEW_STRINGVALUE - MENUITEM "&Binary Value", ID_EDIT_NEW_BINARYVALUE - MENUITEM "&DWORD Value", ID_EDIT_NEW_DWORDVALUE - MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE - MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + MENUITEM "&Řetězec", ID_EDIT_NEW_STRINGVALUE + MENUITEM "&Binární hodnota", ID_EDIT_NEW_BINARYVALUE + MENUITEM "&Hodnota DWORD", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Víceřetězcová hodnota", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Rozšiřitelná řetězcová hodnota", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END - MENUITEM "&Find", ID_EDIT_FIND + MENUITEM "&Najít", ID_EDIT_FIND MENUITEM SEPARATOR - MENUITEM "&Delete", ID_TREE_DELETE - MENUITEM "&Rename", ID_TREE_RENAME + MENUITEM "&Odstranit", ID_TREE_DELETE + MENUITEM "&Přejmenovat", ID_TREE_RENAME MENUITEM SEPARATOR - MENUITEM "&Export", ID_TREE_EXPORT - MENUITEM "&Permissions...", ID_TREE_PERMISSIONS, GRAYED + MENUITEM "&Exportovat", ID_TREE_EXPORT + MENUITEM "Oprá&vnění...", ID_TREE_PERMISSIONS, GRAYED MENUITEM SEPARATOR - MENUITEM "&Copy Key Name", ID_EDIT_COPYKEYNAME + MENUITEM "Z&kopírovat název klíče", ID_EDIT_COPYKEYNAME END END @@ -287,22 +285,22 @@ BEGIN ID_EDIT_DELETE "Smaže výběr" ID_EDIT_RENAME "Přejmenuje výběr" ID_EDIT_COPYKEYNAME "Zkopíruje název klíče do schránky" - ID_EDIT_FIND "Hledá textový řetězec v klíči, položkách, nebo datech" - ID_EDIT_FINDNEXT "Hledá další výskyt textu zadaného v předchozím hledání" + ID_EDIT_FIND "Vyhledá textový řetězec v klíči, položkách, nebo datech" + ID_EDIT_FINDNEXT "Vyhledá další výskyt textu zadaného v předchozím hledání" END STRINGTABLE DISCARDABLE BEGIN - IDS_ERROR "Chyba" - IDS_WARNING "Upozornění" - IDS_BAD_KEY "Can't query key '%s'" + IDS_ERROR "Chyba" + IDS_WARNING "Upozornění" + IDS_BAD_KEY "Nelze se dotázat klíče '%s'" IDS_BAD_VALUE "Nelze se dotázat položky '%s'" IDS_UNSUPPORTED_TYPE "Nelze upravovat klíče tohoto typu (%ld)" IDS_TOO_BIG_VALUE "Položka je příliš velká (%ld)" IDS_MULTI_SZ_EMPTY_STRING "Položky typu REG_MULTI_SZ nemohou obsahovat prázdné řetezce.\nPrázdné řetězce byly odebrány ze seznamu." - IDS_QUERY_DELETE_KEY_ONE "Are you sure you want to delete this key?" - IDS_QUERY_DELETE_KEY_MORE "Are you sure you want to delete these keys?" - IDS_QUERY_DELETE_KEY_CONFIRM "Confirm Key Delete" + IDS_QUERY_DELETE_KEY_ONE "Opravdu chcete odstranit tento klíč?" + IDS_QUERY_DELETE_KEY_MORE "Opravdu chcete odstranit tyto klíče?" + IDS_QUERY_DELETE_KEY_CONFIRM "Potvrzení smazání klíče" IDS_QUERY_DELETE_ONE "Opravdu chcete odstranit tuto položku?" IDS_QUERY_DELETE_MORE "Opravdu chcete odstranit tyto položky?" IDS_QUERY_DELETE_CONFIRM "Potvrzení odstranění položky" @@ -310,8 +308,8 @@ BEGIN IDS_ERR_DELETEVALUE "Nelze odstranit všechny vybrané položky!" IDS_ERR_RENVAL_CAPTION "Chyba při přejmenování položky" IDS_ERR_RENVAL_TOEMPTY "Nelze přejmenovat %s. Vybraná položka je prázdná. Vyzkoušejte jiný název." - IDS_NEW_KEY "New Key #%d" - IDS_NEW_VALUE "New Value #%d" + IDS_NEW_KEY "Nový klíč #%d" + IDS_NEW_VALUE "Nová hodnota #%d" END STRINGTABLE DISCARDABLE @@ -328,7 +326,7 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_FLT_REGFILE "Registration File" + IDS_FLT_REGFILE "Soubor registru" IDS_FLT_REGFILES "Soubory registru" IDS_FLT_REGFILES_FLT "*.reg" IDS_FLT_REGEDIT4 "Soubory registru Win9x/NT4 (REGEDIT4)" @@ -362,10 +360,10 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_EXPAND "&Expand" - IDS_COLLAPSE "&Collapse" - IDS_GOTO_SUGGESTED_KEY "&Go to '%s'" - IDS_FINISHEDFIND "Finished searching through the registry." + IDS_EXPAND "&Rozbalit" + IDS_COLLAPSE "&Sbalit" + IDS_GOTO_SUGGESTED_KEY "&Jít na '%s'" + IDS_FINISHEDFIND "Prohledávání registru bylo dokončeno." END /*****************************************************************/ @@ -376,70 +374,69 @@ END */ IDD_EXPORTRANGE DIALOGEX DISCARDABLE 50, 50, 370, 50 -STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | - WS_BORDER +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Export Range",IDC_STATIC,2,0,366,48 - CONTROL "&All",IDC_EXPORT_ALL,"Button",BS_AUTORADIOBUTTON,10,10, 29,11 - CONTROL "S&elected Branch",IDC_EXPORT_BRANCH,"Button",BS_AUTORADIOBUTTON,10,22, 100,11 + GROUPBOX "Rozsah exportu",IDC_STATIC,2,0,366,48 + CONTROL "&Vše",IDC_EXPORT_ALL,"Button",BS_AUTORADIOBUTTON,10,10, 29,11 + CONTROL "V&ybraná větev",IDC_EXPORT_BRANCH,"Button",BS_AUTORADIOBUTTON,10,22, 100,11 EDITTEXT IDC_EXPORT_BRANCH_TEXT,30,34,335,12 END IDD_ADDFAVORITES DIALOGEX DISCARDABLE 0, 0, 186, 46 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add to Favorites" +CAPTION "Přidat do Oblíbených" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK",IDOK,129,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 - LTEXT "&Favorite Name:",IDC_STATIC,7,7,70,10 + PUSHBUTTON "Storno",IDCANCEL,129,24,50,14 + LTEXT "&Název oblíbené položky:",IDC_STATIC,7,7,70,10 EDITTEXT IDC_FAVORITENAME,7,26,110,13,ES_AUTOHSCROLL END IDD_REMOVEFAVORITES DIALOGEX DISCARDABLE 0, 0, 164, 135 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Remove Favorites" +CAPTION "Odebrat z Oblíbených" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK",IDOK,107,114,50,14 - PUSHBUTTON "Cancel",IDCANCEL,7,114,50,14 + PUSHBUTTON "Storno",IDCANCEL,7,114,50,14 CONTROL "List1",IDC_FAVORITESLIST,"SysListView32",LVS_LIST | WS_BORDER | WS_TABSTOP,7,20,150,90 - LTEXT "Select Favorite(s):",IDC_STATIC,7,7,99,12 + LTEXT "Vyberte Oblíbené:",IDC_STATIC,7,7,99,12 END IDD_FIND DIALOGEX DISCARDABLE 0, 0, 254, 82 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find" +CAPTION "Najít" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Find Next",IDOK,197,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,197,24,50,14 + DEFPUSHBUTTON "Najít &další",IDOK,197,7,50,14 + PUSHBUTTON "Storno",IDCANCEL,197,24,50,14 GROUPBOX "Look at",IDC_STATIC,7,25,63,51 - LTEXT "Fi&nd what:",IDC_STATIC,7,8,37,10 + LTEXT "&Najít:",IDC_STATIC,7,8,37,10 EDITTEXT IDC_FINDWHAT,47,7,142,13,ES_AUTOHSCROLL - CONTROL "&Keys",IDC_LOOKAT_KEYS,"Button",BS_AUTOCHECKBOX | + CONTROL "&Klíče",IDC_LOOKAT_KEYS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,36,35,8 - CONTROL "&Values",IDC_LOOKAT_VALUES,"Button",BS_AUTOCHECKBOX | + CONTROL "&Hodnoty",IDC_LOOKAT_VALUES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,48,36,8 CONTROL "&Data",IDC_LOOKAT_DATA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,60,42,8 - CONTROL "Match &whole string only",IDC_MATCHSTRING,"Button", + CONTROL "Hledat pouze &celý řetězec",IDC_MATCHSTRING,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,83,32,94,13 - CONTROL "Match &case",IDC_MATCHCASE,"Button",BS_AUTOCHECKBOX | + CONTROL "Rozlišovat &velikost písmen",IDC_MATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,83,48,90,12 END IDD_FINDING DIALOGEX 0, 0, 145, 50 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find" +CAPTION "Najít" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN ICON IDI_REGEDIT,IDC_STATIC,7,7,20,20 - DEFPUSHBUTTON "&Cancel",IDCANCEL,93,29,45,14 - LTEXT "Searching the registry...",IDC_STATIC,33,12,83,8 + DEFPUSHBUTTON "Storno",IDCANCEL,93,29,45,14 + LTEXT "Probíhá prohledávání registru...",IDC_STATIC,33,12,83,8 END /* diff --git a/base/applications/regedit/lang/it-IT.rc b/base/applications/regedit/lang/it-IT.rc index 47960b8da5b..f5a2fc96540 100644 --- a/base/applications/regedit/lang/it-IT.rc +++ b/base/applications/regedit/lang/it-IT.rc @@ -192,7 +192,7 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | CAPTION "Modifica Multi-Stringa" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "&Name:",IDC_STATIC,6,6,134,8 + LTEXT "&Nome:",IDC_STATIC,6,6,134,8 EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY LTEXT "&Dati:",IDC_STATIC,6,35,161,8 EDITTEXT IDC_VALUE_DATA,6,46,240,102,ES_MULTILINE | diff --git a/base/applications/regedit/listview.c b/base/applications/regedit/listview.c index 6e95a863ff9..12cfa894db6 100644 --- a/base/applications/regedit/listview.c +++ b/base/applications/regedit/listview.c @@ -380,7 +380,7 @@ static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSor if (g_columnToSort == 2) { /* FIXME: Sort on value */ } - return g_invertSort ? _tcscmp(r->name, l->name) : _tcscmp(l->name, r->name); + return g_invertSort ? _tcsicmp(r->name, l->name) : _tcsicmp(l->name, r->name); } BOOL ListWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result) diff --git a/base/applications/sndvol32/lang/cs-CZ.rc b/base/applications/sndvol32/lang/cs-CZ.rc index 9f89248021a..abeec0eb9db 100644 --- a/base/applications/sndvol32/lang/cs-CZ.rc +++ b/base/applications/sndvol32/lang/cs-CZ.rc @@ -1,3 +1,9 @@ +/* FILE: applications/sndvol32/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * THANKS TO: Denzil, who translated major part of this file + * UPDATED: 2010-05-25 + */ + LANGUAGE LANG_CZECH, SUBLANG_DEFAULT IDM_MAINMENU MENU DISCARDABLE @@ -5,7 +11,7 @@ BEGIN POPUP "&Nastavení" BEGIN MENUITEM "&Možnosti", IDC_PROPERTIES - MENUITEM "&Rozšířené nastevení", IDC_ADVANCED_CONTROLS + MENUITEM "&Rozšířené nastavení", IDC_ADVANCED_CONTROLS MENUITEM SEPARATOR MENUITEM "&Konec", IDC_EXIT END @@ -35,9 +41,9 @@ BEGIN PUSHBUTTON "&Záznam", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON PUSHBUTTON "&Jiné:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED - LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8 + LTEXT "Zobrazit tyto ovladače hlasitosti:", IDC_LABELCONTROLS, 7, 109, 162, 8 CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96 PUSHBUTTON "OK", IDOK, 114,226,50,14 - PUSHBUTTON "Zrušit", IDCANCEL, 168,226,50,14 + PUSHBUTTON "Storno", IDCANCEL, 168,226,50,14 END diff --git a/base/setup/usetup/errorcode.h b/base/setup/usetup/errorcode.h index 4ecc11d35d2..79461a7e39c 100644 --- a/base/setup/usetup/errorcode.h +++ b/base/setup/usetup/errorcode.h @@ -65,6 +65,7 @@ typedef enum ERROR_UPDATE_LOCALESETTINGS, ERROR_ADDING_KBLAYOUTS, ERROR_UPDATE_GEOID, + ERROR_INSUFFICIENT_DISKSPACE, ERROR_LAST_ERROR_CODE }ERROR_NUMBER; diff --git a/base/setup/usetup/interface/usetup.c b/base/setup/usetup/interface/usetup.c index 7a97b492c27..57b4efca6bd 100644 --- a/base/setup/usetup/interface/usetup.c +++ b/base/setup/usetup/interface/usetup.c @@ -31,6 +31,7 @@ #define NDEBUG #include + /* GLOBALS ******************************************************************/ HANDLE ProcessHeap; @@ -81,6 +82,8 @@ static PGENERIC_LIST LanguageList = NULL; static LANGID LanguageId = 0; +static ULONG RequiredPartitionDiskSpace = ~0; + /* FUNCTIONS ****************************************************************/ static VOID @@ -720,6 +723,7 @@ SetupStartPage(PINPUT_RECORD Ir) UINT ErrorLine; ULONG ReturnSize; PGENERIC_LIST_ENTRY ListEntry; + INT IntValue; CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); @@ -800,6 +804,22 @@ SetupStartPage(PINPUT_RECORD Ir) return QUIT_PAGE; } + /* Open 'DiskSpaceRequirements' section */ + if (!SetupFindFirstLineW(SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context)) + { + MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; + } + + /* Get the 'FreeSysPartDiskSpace' value */ + if (!SetupGetIntField(&Context, 1, &IntValue)) + { + MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; + } + + RequiredPartitionDiskSpace = (ULONG)IntValue; + /* Start PnP thread */ if (hPnpThread != INVALID_HANDLE_VALUE) { @@ -829,7 +849,7 @@ SetupStartPage(PINPUT_RECORD Ir) while (ListEntry != NULL) { - if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry))) + if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) { DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry)); SetCurrentListEntry(LanguageList, ListEntry); @@ -843,7 +863,7 @@ SetupStartPage(PINPUT_RECORD Ir) while (ListEntry != NULL) { - if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry))) + if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) { DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry)); SetCurrentListEntry(LayoutList, ListEntry); @@ -1381,6 +1401,31 @@ LayoutSettingsPage(PINPUT_RECORD Ir) return DISPLAY_SETTINGS_PAGE; } +static BOOL IsDiskSizeValid(PPARTENTRY PartEntry) +{ + ULONGLONG m; + /* check for unpartitioned space */ + m = PartEntry->UnpartitionedLength; + m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */ + if( m > RequiredPartitionDiskSpace) + { + return TRUE; + } + + // check for partitioned space + m = PartEntry->PartInfo[0].PartitionLength.QuadPart; + m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */ + if( m < RequiredPartitionDiskSpace) + { + /* partition is too small so ask for another partion */ + DPRINT1("Partition is too small, required disk space is %lu MB\n", RequiredPartitionDiskSpace); + return FALSE; + } + else + { + return TRUE; + } +} static PAGE_NUMBER SelectPartitionPage(PINPUT_RECORD Ir) @@ -1434,9 +1479,13 @@ SelectPartitionPage(PINPUT_RECORD Ir) { if (AutoPartition) { - PPARTENTRY PartEntry = PartEntry = PartitionList->CurrentPartition; + PPARTENTRY PartEntry = PartitionList->CurrentPartition; ULONG MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; /* in MBytes (rounded) */ - + if(!IsDiskSizeValid(PartitionList->CurrentPartition)) + { + MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); + return SELECT_PARTITION_PAGE; /* let the user select another partition */ + } CreateNewPartition(PartitionList, MaxSize, TRUE); @@ -1446,6 +1495,11 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else { + if(!IsDiskSizeValid(PartitionList->CurrentPartition)) + { + MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); + return SELECT_PARTITION_PAGE; /* let the user select another partition */ + } return(SELECT_FILE_SYSTEM_PAGE); } } @@ -1489,6 +1543,11 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ { + if(!IsDiskSizeValid(PartitionList->CurrentPartition)) + { + MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY); + return SELECT_PARTITION_PAGE; /* let the user select another partition */ + } if (PartitionList->CurrentPartition == NULL || PartitionList->CurrentPartition->Unpartitioned == TRUE) { @@ -3121,7 +3180,7 @@ FileCopyCallback(PVOID Context, case SPFILENOTIFY_STARTCOPY: /* Display copy message */ - CONSOLE_SetStatusTextAutoFitX (45 , MUIGetString(STRING_COPYING), (PWSTR)Param1); + CONSOLE_SetStatusText(MUIGetString(STRING_COPYING), (PWSTR)Param1); SetupUpdateMemoryInfo(CopyContext, FALSE); break; diff --git a/base/setup/usetup/lang/bg-BG.h b/base/setup/usetup/lang/bg-BG.h index 23bd1f4ebf3..b6b22fdbf13 100644 --- a/base/setup/usetup/lang/bg-BG.h +++ b/base/setup/usetup/lang/bg-BG.h @@ -1488,6 +1488,12 @@ MUI_ERROR bgBGErrorEntries[] = "Ť áâŕ®©Ş â  ­Ą ¬®¦  ¤  ăáâ ­®˘¨ ®§­ ç¨âĄ«ď ­  ŁĄ®Łŕ äáŞ®â® Ż®«®¦Ą­¨Ą.\n" "ENTER = ŹŕĄ§ Żă᪠­Ą ­  Ş®¬Żîâęŕ " }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Ť â¨á­ĄâĄ Ş« ˘¨č, §  ¤  Żŕ®¤ę«¦¨âĄ.", + NULL + }, { NULL, NULL @@ -1626,7 +1632,7 @@ MUI_STRING bgBGStrings[] = {STRING_TXTSETUPFAILED, "ŤĄ ˇĄ ­ ¬ĄŕĄ­ ŕ §¤Ą« '%S'\n˘ TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 ‡ Ż¨á ­  ä ©«: %S"}, + " ‡ Ż¨á ­  ä ©«: %S"}, {STRING_SETUPCOPYINGFILES, "’ĄçĄ § Ż¨á˘ ­Ą ­  ä ©«®˘ĄâĄ..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/cs-CZ.h b/base/setup/usetup/lang/cs-CZ.h index b3397e14751..428b0f55fea 100644 --- a/base/setup/usetup/lang/cs-CZ.h +++ b/base/setup/usetup/lang/cs-CZ.h @@ -1,7 +1,7 @@ /* FILE: setup/usetup/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) * THANKS TO: preston - * UPDATED: 2008-06-05 + * UPDATED: 2010-05-25 */ #pragma once @@ -1481,8 +1481,14 @@ MUI_ERROR csCZErrorEntries[] = }, { //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" + "Nepodaýilo se nastavit geo id.\n" + "ENTER = Restartovat poźˇtaź" + }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Na zvolen‚m oddˇlu nenˇ dost voln‚ho mˇsta.\n" + " * Pokraźujte stisknutˇm libovoln‚ kl vesy.", + NULL }, { NULL, @@ -1622,7 +1628,7 @@ MUI_STRING csCZStrings[] = {STRING_TXTSETUPFAILED, "Nepodaýilo se najˇt sekci '%S' v souboru\n TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kopˇruji soubor: %S"}, + " Kopˇruji soubor: %S"}, {STRING_SETUPCOPYINGFILES, "Instalace kopˇruje soubory..."}, {STRING_REGHIVEUPDATE, @@ -1662,7 +1668,7 @@ MUI_STRING csCZStrings[] = {STRING_HDDINFOUNK1, "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)."}, {STRING_HDDINFOUNK2, - " %c%c Type %lu %I64u %s"}, + " %c%c Typ %lu %I64u %s"}, {STRING_HDINFOPARTDELETE, "na %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) na %wZ."}, {STRING_HDDINFOUNK3, diff --git a/base/setup/usetup/lang/de-DE.h b/base/setup/usetup/lang/de-DE.h index e21b2ffc001..4686873427a 100644 --- a/base/setup/usetup/lang/de-DE.h +++ b/base/setup/usetup/lang/de-DE.h @@ -1477,7 +1477,13 @@ MUI_ERROR deDEErrorEntries[] = "Setup konnte den geografischen Standort nicht einstellen.\n" "ENTER = Computer neu starten" }, -{ + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Nicht genug Speicherplatz auf der gew„hlten Partition vorhanden.\n" + " * Eine beliebige Taste zum Fortsetzen drcken.", + NULL + }, + { NULL, NULL } @@ -1615,7 +1621,7 @@ MUI_STRING deDEStrings[] = {STRING_TXTSETUPFAILED, "Setup konnte die '%S'-Sektion\nin TXTSETUP.SIF nicht finden.\n"}, {STRING_COPYING, - "\xB3 Kopiere Datei: %S"}, + " Kopiere Datei: %S"}, {STRING_SETUPCOPYINGFILES, "Setup kopiert Dateien..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/el-GR.h b/base/setup/usetup/lang/el-GR.h index e04f530f674..66de19aa71a 100644 --- a/base/setup/usetup/lang/el-GR.h +++ b/base/setup/usetup/lang/el-GR.h @@ -1644,7 +1644,7 @@ MUI_STRING elGRStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 €¤« š¨á­ś«  «¦ ¨®śĺ¦: %S"}, + " €¤« š¨á­ś«  «¦ ¨®śĺ¦: %S"}, {STRING_SETUPCOPYINGFILES, "† śšˇ«á©«©ž ¤« š¨á­ś  ¨®śĺ..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/en-US.h b/base/setup/usetup/lang/en-US.h index ac694c98c54..9038002050d 100644 --- a/base/setup/usetup/lang/en-US.h +++ b/base/setup/usetup/lang/en-US.h @@ -93,7 +93,7 @@ static MUI_ENTRY enUSWelcomePageEntries[] = { 8, 19, - "\x07 Press L to view the ReactOS Licensing Terms and Conditions", + "\x07 Press L to view the ReactOS Licensing Terms and Conditions.", TEXT_STYLE_NORMAL }, { @@ -1476,6 +1476,12 @@ MUI_ERROR enUSErrorEntries[] = "Setup could not set the geo id.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1613,7 +1619,7 @@ MUI_STRING enUSStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copying file: %S"}, + " Copying file: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is copying files..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/es-ES.h b/base/setup/usetup/lang/es-ES.h index d951d6b564f..bc2fe1340af 100644 --- a/base/setup/usetup/lang/es-ES.h +++ b/base/setup/usetup/lang/es-ES.h @@ -18,7 +18,7 @@ static MUI_ENTRY esESLanguagePageEntries[] = { 6, 8, - "Selecci˘n de idioma", + "Selecci˘n del idioma", TEXT_STYLE_NORMAL }, { @@ -94,7 +94,7 @@ static MUI_ENTRY esESWelcomePageEntries[] = { 8, 19, - "\x07 Presione L para ver las condiciones y t‚rminos de licencia", + "\x07 Presione L para ver las condiciones y t‚rminos de licencia.", TEXT_STYLE_NORMAL }, { @@ -194,18 +194,24 @@ static MUI_ENTRY esESIntroPageEntries[] = { 8, 19, - "- El comprobador de integridad del sistema de archivos no est  aŁn implementado.", + "- El comprobador de integridad del sistema de archivos no est  aŁn", TEXT_STYLE_NORMAL }, { 8, - 23, - "\x07 Presione ENTER para instalar ReactOS.", + 20, + " implementado.", TEXT_STYLE_NORMAL }, { 8, 25, + "\x07 Presione ENTER para instalar ReactOS.", + TEXT_STYLE_NORMAL + }, + { + 8, + 27, "\x07 Presione F3 para salir sin instalar ReactOS.", TEXT_STYLE_NORMAL }, @@ -358,7 +364,7 @@ static MUI_ENTRY esESDevicePageEntries[] = { 6, 8, - "La lista inferior muestra la configuraci˘n del dispositivo actual.", + "La lista inferior muestra la configuraci˘n actual de dispositivos.", TEXT_STYLE_NORMAL }, { @@ -1469,15 +1475,21 @@ MUI_ERROR esESErrorEntries[] = }, { //ERROR_ADDING_KBLAYOUTS, - "Setup failed to add keyboard layouts to registry.\n" - "ENTER = Reboot computer" + "El instalador no ha podido agregar los layouts de teclado al registro.\n" + "ENTER = Reiniciar el equipo" }, { //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" + "El instalador no ha podido configurar el ID geogr fico.\n" + "ENTER = Reiniciar el equipo" }, -{ + { + //ERROR_INSUFFICIENT_DISKSPACE, + "No hay suficiente espacio disponible en la partici˘n seleccionada.\n" + " * Presione una tecla para continuar.", + NULL + }, + { NULL, NULL } @@ -1592,7 +1604,7 @@ MUI_STRING esESStrings[] = {STRING_INSTALLDELETEPARTITION, " ENTER = Instalar D = Borrar Partici˘n F3 = Salir"}, {STRING_PARTITIONSIZE, - "Tamańo de la nueva partici˘n:"}, + "Tama¤o de la nueva partici˘n:"}, {STRING_CHOOSENEWPARTITION, "Ha elegido crear una nueva partici˘n en"}, {STRING_HDDSIZE, @@ -1614,7 +1626,7 @@ MUI_STRING esESStrings[] = {STRING_TXTSETUPFAILED, "El instalador fall˘ al buscar la secci˘n\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copiando archivo: %S"}, + " Copiando archivo: %S"}, {STRING_SETUPCOPYINGFILES, "El instalador est  copiando archivos..."}, {STRING_REGHIVEUPDATE, @@ -1690,6 +1702,6 @@ MUI_STRING esESStrings[] = {STRING_GB, "GB"}, {STRING_ADDKBLAYOUTS, - "Adding keyboard layouts"}, + "A¤adiendo disposici˘n de teclado"}, {0, 0} }; diff --git a/base/setup/usetup/lang/et-EE.h b/base/setup/usetup/lang/et-EE.h index 4a1f7bda62b..f0b7e8bd328 100644 --- a/base/setup/usetup/lang/et-EE.h +++ b/base/setup/usetup/lang/et-EE.h @@ -1473,6 +1473,12 @@ MUI_ERROR etEEErrorEntries[] = "Geograafilist asukohta ei ännestunud seadistada.\n" "ENTER = Taask„ivita arvuti" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Valitud partitsioonil pole piisavalt ruumi.\n" + " * Vajuta suvalist klahvi, et j„tkata.", + NULL + }, { NULL, NULL @@ -1609,9 +1615,9 @@ MUI_STRING etEEStrings[] = {STRING_REBOOTCOMPUTER, "ENTER = Taask„ivita arvuti"}, {STRING_TXTSETUPFAILED, - "TXTSETUP.SIF failist ei leitud '%S' sektsiooni\n"}, + "TXTSETUP.SIF failist ei leitud '%S' sektsiooni\n"}, {STRING_COPYING, - "\xB3 Kopeerimine: %S"}, + " Kopeerimine: %S"}, {STRING_SETUPCOPYINGFILES, "Failide kopeerimine..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/fr-FR.h b/base/setup/usetup/lang/fr-FR.h index ae037aba25f..aa3b3df809a 100644 --- a/base/setup/usetup/lang/fr-FR.h +++ b/base/setup/usetup/lang/fr-FR.h @@ -1489,6 +1489,12 @@ MUI_ERROR frFRErrorEntries[] = "Setup could not set the geo id.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1627,7 +1633,7 @@ MUI_STRING frFRStrings[] = {STRING_TXTSETUPFAILED, "Setup n'a pu trouver la section '%S'\ndans TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copie du fichier: %S"}, + " Copie du fichier: %S"}, {STRING_SETUPCOPYINGFILES, "Setup copie les fichiers..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/it-IT.h b/base/setup/usetup/lang/it-IT.h index bb220000c84..3b4ac5670cd 100644 --- a/base/setup/usetup/lang/it-IT.h +++ b/base/setup/usetup/lang/it-IT.h @@ -94,7 +94,7 @@ static MUI_ENTRY itITWelcomePageEntries[] = { 8, 19, - "\x07 Premere L per vedere i termini e condizioni della licenza", + "\x07 Premere L per vedere i termini e condizioni della licenza.", TEXT_STYLE_NORMAL }, { @@ -158,7 +158,7 @@ static MUI_ENTRY itITIntroPageEntries[] = { 6, 12, - "Ci sono delle limitazioni:", + "Si applicano le seguenti limitazioni:", TEXT_STYLE_NORMAL }, { @@ -358,7 +358,7 @@ static MUI_ENTRY itITDevicePageEntries[] = { 6, 8, - "La lista inferiore mostra la configurazione della periferica corrente.", + "L'elenco che segue mostra le impostazioni correnti delle periferiche.", TEXT_STYLE_NORMAL }, { @@ -382,7 +382,7 @@ static MUI_ENTRY itITDevicePageEntries[] = { 3, 14, - "Nazionalit… tastiera:", + "Layout di tastiera:", TEXT_STYLE_NORMAL }, { @@ -393,7 +393,7 @@ static MUI_ENTRY itITDevicePageEntries[] = }, { 25, - 16, "Procedere con questa configurazione", + 16, "Accettare queste impostazioni", TEXT_STYLE_NORMAL }, { @@ -423,7 +423,7 @@ static MUI_ENTRY itITDevicePageEntries[] = { 6, 24, - "\"Procedere con questa configurazione\" e premere INVIO.", + "\"Accettare queste impostazioni\" e premere INVIO.", TEXT_STYLE_NORMAL }, { @@ -1474,8 +1474,14 @@ MUI_ERROR itITErrorEntries[] = }, { //ERROR_UPDATE_GEOID, - "Setup could not set the geo id.\n" - "ENTER = Reboot computer" + "Setup non ha potuto impostare l'id geografico.\n" + "INVIO = Riavviare il computer" + }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Lo spazio disponibile nella partizione selezionata Š insufficiente.\n" + " * Premere un tasto qualsiasi per continuare.", + NULL }, { NULL, @@ -1615,7 +1621,7 @@ MUI_STRING itITStrings[] = {STRING_TXTSETUPFAILED, "Setup non ha trovato la sezione '%S' \nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copia di: %S"}, + " Copia di: %S"}, {STRING_SETUPCOPYINGFILES, "Copia dei file in corso..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/ja-JP.h b/base/setup/usetup/lang/ja-JP.h index af7ccdf2a7e..03b6ec1841d 100644 --- a/base/setup/usetup/lang/ja-JP.h +++ b/base/setup/usetup/lang/ja-JP.h @@ -1477,6 +1477,12 @@ MUI_ERROR jaJPErrorEntries[] = "ľŻÄ±ŻĚßĘ geo id ¦ ľŻĂ˛ ĂŢ·ĎľÝ ĂŢĽŔˇ\n" "ENTER = şÝËß­°ŔÉ »˛·ÄŢł" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1614,7 +1620,7 @@ MUI_STRING jaJPStrings[] = {STRING_TXTSETUPFAILED, "ľŻÄ±ŻĚßĘ TXTSETUP.SIF É '%S' ľ¸Ľ®ÝÉ ąÝĽ­ÂĆ\nĽŻĘ߲ ĽĎĽŔˇ\n"}, {STRING_COPYING, - "\xB3 şËß° Á­łÉ ̧˛Ů: %S"}, + " şËß° Á­łÉ ̧˛Ů: %S"}, {STRING_SETUPCOPYINGFILES, "ľŻÄ±ŻĚßĘ Ě§˛Ů¦ şËß° ĽĂ ˛Ď˝..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/lt-LT.h b/base/setup/usetup/lang/lt-LT.h index a0a9eb485bf..7020ebbaba1 100644 --- a/base/setup/usetup/lang/lt-LT.h +++ b/base/setup/usetup/lang/lt-LT.h @@ -1486,6 +1486,12 @@ MUI_ERROR ltLTErrorEntries[] = "Setup could not set the geo id.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1624,7 +1630,7 @@ MUI_STRING ltLTStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copying file: %S"}, + " Copying file: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is copying files..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/nl-NL.h b/base/setup/usetup/lang/nl-NL.h index eba2d93ad5c..0141359d290 100644 --- a/base/setup/usetup/lang/nl-NL.h +++ b/base/setup/usetup/lang/nl-NL.h @@ -1504,6 +1504,12 @@ MUI_ERROR nlNLErrorEntries[] = "Setup kan de geografische positie niet instellen.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1642,7 +1648,7 @@ MUI_STRING nlNLStrings[] = {STRING_TXTSETUPFAILED, "Setup kan de '%S' sectie niet vinden\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kopieeren bestand: %S"}, + " Kopieeren bestand: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is bestand aan het kopieeren..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/pl-PL.h b/base/setup/usetup/lang/pl-PL.h index 8d4262d58cd..de0a55fcd5c 100644 --- a/base/setup/usetup/lang/pl-PL.h +++ b/base/setup/usetup/lang/pl-PL.h @@ -1485,6 +1485,12 @@ MUI_ERROR plPLErrorEntries[] = "Instalator nie m˘g ustawi† lokalizacji geograficznej.\n" "ENTER = Restart komputera" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Brak wystarczajĄcej wolnej przestrzeni w wybranej partycji.\n" + " * Nacinij dowolny klawisz aby kontynuowa†.", + NULL + }, { NULL, NULL @@ -1623,7 +1629,7 @@ MUI_STRING plPLStrings[] = {STRING_TXTSETUPFAILED, "Instalator nie by w stanie odnale«† sekji '%S'\nw pliku TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kopiowanie plik˘w: %S"}, + " Kopiowanie plik˘w: %S"}, {STRING_SETUPCOPYINGFILES, "Instalator kopiuje pliki..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/ru-RU.h b/base/setup/usetup/lang/ru-RU.h index 7e55b9700bb..b74d17b8e1a 100644 --- a/base/setup/usetup/lang/ru-RU.h +++ b/base/setup/usetup/lang/ru-RU.h @@ -1477,6 +1477,12 @@ MUI_ERROR ruRUErrorEntries[] = "Setup could not set the geo id.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1615,7 +1621,7 @@ MUI_STRING ruRUStrings[] = {STRING_TXTSETUPFAILED, "Źŕ®Łŕ ¬¬  ăáâ ­®˘Ş¨ ­Ą á¬®Ł«  ­ ©â¨ ᥪć¨î '%S'\n˘ ä ©«Ą TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Š®Ż¨ŕ®˘ ­¨Ą: %S"}, + " Š®Ż¨ŕ®˘ ­¨Ą: %S"}, {STRING_SETUPCOPYINGFILES, "Źŕ®Łŕ ¬¬  ăáâ ­®˘Ş¨ Ş®Ż¨ŕăĄâ ä ©«ë..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/sk-SK.h b/base/setup/usetup/lang/sk-SK.h index 5078f08139f..5bb0d60fb53 100644 --- a/base/setup/usetup/lang/sk-SK.h +++ b/base/setup/usetup/lang/sk-SK.h @@ -1487,6 +1487,12 @@ MUI_ERROR skSKErrorEntries[] = "Inçtal tor nemohol nastaviś geo id.\n" "ENTER = Reçtart poźˇtaźa" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1625,7 +1631,7 @@ MUI_STRING skSKStrings[] = {STRING_TXTSETUPFAILED, "Inçtal tor zlyhal pri h–adanˇ sekcie '%S'\nv sŁbore TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Kopˇruje sa sŁbor: %S"}, + " Kopˇruje sa sŁbor: %S"}, {STRING_SETUPCOPYINGFILES, "Inçtal tor kopˇruje sŁbory..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/sv-SE.h b/base/setup/usetup/lang/sv-SE.h index 0dbffdc453c..17b0fa5ddad 100644 --- a/base/setup/usetup/lang/sv-SE.h +++ b/base/setup/usetup/lang/sv-SE.h @@ -1477,6 +1477,12 @@ MUI_ERROR svSEErrorEntries[] = "Setup could not set the geo id.\n" "ENTER = Reboot computer" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1614,7 +1620,7 @@ MUI_STRING svSEStrings[] = {STRING_TXTSETUPFAILED, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Copying file: %S"}, + " Copying file: %S"}, {STRING_SETUPCOPYINGFILES, "Setup is copying files..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/usetup/lang/uk-UA.h b/base/setup/usetup/lang/uk-UA.h index ba3fd009623..7f7a7a7b7e1 100644 --- a/base/setup/usetup/lang/uk-UA.h +++ b/base/setup/usetup/lang/uk-UA.h @@ -1483,6 +1483,12 @@ MUI_ERROR ukUAErrorEntries[] = "ŤĄ ˘¤ «®áě ˘áâ ­®˘¨â¨ geo id.\n" "ENTER = ŹĄŕĄ§ ˘ ­â ¦¨â¨ Ş®¬Ż'îâĄŕ" }, + { + //ERROR_INSUFFICIENT_DISKSPACE, + "Not enough free space in the selected partition.\n" + " * Press any key to continue.", + NULL + }, { NULL, NULL @@ -1620,7 +1626,7 @@ MUI_STRING ukUAStrings[] = {STRING_TXTSETUPFAILED, "‚áâ ­®˘«î˘ ç ­Ą §¬iŁ §­ ©â¨ ᥪćiî '%S' \n˘ ä ©«i TXTSETUP.SIF.\n"}, {STRING_COPYING, - "\xB3 Š®Żi­­ď: %S"}, + " Š®Żi­­ď: %S"}, {STRING_SETUPCOPYINGFILES, "‚áâ ­®˘«î˘ ç Ş®Żiîó ä ©«¨..."}, {STRING_REGHIVEUPDATE, diff --git a/base/setup/welcome/lang/es-ES.rc b/base/setup/welcome/lang/es-ES.rc index 8d95d5cc1a5..3d44ee308d0 100644 --- a/base/setup/welcome/lang/es-ES.rc +++ b/base/setup/welcome/lang/es-ES.rc @@ -9,7 +9,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_APPTITLE "ReactOS - Bienvenido" IDS_DEFAULTTOPICTITLE "ReactOS" - IDS_DEFAULTTOPICDESC "Bienvenido al Sistema Operativo React.\n\nHaz Click en una opcion a la izquierda." + IDS_DEFAULTTOPICDESC "Bienvenido al Sistema Operativo React.\n\nHaz Click en una opción a la izquierda." // IDS_CHECKTEXT "Mostrar este dialogo otra vez" // IDS_CLOSETEXT "Salir" END diff --git a/base/shell/cmd/cmd.c b/base/shell/cmd/cmd.c index 59f00eada0a..54ff9b23edc 100644 --- a/base/shell/cmd/cmd.c +++ b/base/shell/cmd/cmd.c @@ -156,7 +156,7 @@ BOOL bCanExit = TRUE; /* indicates if this shell is exitable */ BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */ BOOL bIgnoreEcho = FALSE; /* Set this to TRUE to prevent a newline, when executing a command */ INT nErrorLevel = 0; /* Errorlevel of last launched external program */ -BOOL bChildProcessRunning = FALSE; +CRITICAL_SECTION ChildProcessRunningLock; BOOL bUnicodeOutput = FALSE; BOOL bDisableBatchEcho = FALSE; BOOL bDelayedExpansion = FALSE; @@ -436,14 +436,12 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) { if (IsConsoleProcess(prci.hProcess)) { - /* FIXME: Protect this with critical section */ - bChildProcessRunning = TRUE; + EnterCriticalSection(&ChildProcessRunningLock); dwChildProcessId = prci.dwProcessId; WaitForSingleObject (prci.hProcess, INFINITE); - /* FIXME: Protect this with critical section */ - bChildProcessRunning = FALSE; + LeaveCriticalSection(&ChildProcessRunningLock); GetExitCodeProcess (prci.hProcess, &dwExitCode); nErrorLevel = (INT)dwExitCode; @@ -665,9 +663,9 @@ ExecutePipeline(PARSED_COMMAND *Cmd) SetStdHandle(STD_INPUT_HANDLE, hOldConIn); /* Wait for all processes to complete */ - bChildProcessRunning = TRUE; + EnterCriticalSection(&ChildProcessRunningLock); WaitForMultipleObjects(nProcesses, hProcess, TRUE, INFINITE); - bChildProcessRunning = FALSE; + LeaveCriticalSection(&ChildProcessRunningLock); /* Use the exit code of the last process in the pipeline */ GetExitCodeProcess(hProcess[nProcesses - 1], &dwExitCode); @@ -1439,13 +1437,16 @@ BOOL WINAPI BreakHandler (DWORD dwCtrlType) } } - if (bChildProcessRunning == TRUE) + if (!TryEnterCriticalSection(&ChildProcessRunningLock)) { SelfGenerated = TRUE; GenerateConsoleCtrlEvent (dwCtrlType, 0); return TRUE; } - + else + { + LeaveCriticalSection(&ChildProcessRunningLock); + } rec.EventType = KEY_EVENT; rec.Event.KeyEvent.bKeyDown = TRUE; @@ -1797,6 +1798,7 @@ static VOID Cleanup() RemoveBreakHandler (); SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ), ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT ); + DeleteCriticalSection(&ChildProcessRunningLock); } /* @@ -1808,6 +1810,7 @@ int cmd_main (int argc, const TCHAR *argv[]) TCHAR startPath[MAX_PATH]; CONSOLE_SCREEN_BUFFER_INFO Info; + InitializeCriticalSection(&ChildProcessRunningLock); lpOriginalEnvironment = DuplicateEnvironment(); GetCurrentDirectory(MAX_PATH,startPath); diff --git a/base/shell/cmd/copy.c b/base/shell/cmd/copy.c index d451fea09e8..a5bf33eefcb 100644 --- a/base/shell/cmd/copy.c +++ b/base/shell/cmd/copy.c @@ -604,28 +604,30 @@ INT cmd_copy (LPTSTR param) bTouch = TRUE; bDone = TRUE; } - - if(_tcslen(tmpName) == 2) - { - if(tmpName[1] == _T(':')) - { - GetRootPath(tmpName,szSrcPath,MAX_PATH); - } - } - else - /* Get the full path to first file in the string of file names */ - GetFullPathName (tmpName, MAX_PATH, szSrcPath, NULL); } else { bDone = TRUE; - if(_tcslen(arg[nSrc]) == 2 && arg[nSrc][1] == _T(':')) + _tcscpy(tmpName, arg[nSrc]); + } + + /* Get full path or root names */ + if(_tcslen(tmpName) == 2 && tmpName[1] == _T(':')) + { + GetRootPath(tmpName,szSrcPath,MAX_PATH); + } + else + { + /* Get the full path to first file in the string of file names */ + GetFullPathName (tmpName, MAX_PATH, szSrcPath, NULL); + + /* We got a device path of form \\.\x */ + /* FindFirstFile cannot handle this, therefore use the short path */ + if (szSrcPath[0] == _T('\\') && szSrcPath[1] == _T('\\') && + szSrcPath[2] == _T('.') && szSrcPath[3] == _T('\\')) { - GetRootPath(arg[nSrc],szSrcPath,MAX_PATH); + _tcscpy(szSrcPath, tmpName); } - else - /* Get the full path of the source file */ - GetFullPathName (arg[nSrc], MAX_PATH, szSrcPath, NULL); } /* From this point on, we can assume that the shortest path is 3 letters long diff --git a/base/shell/cmd/filecomp.c b/base/shell/cmd/filecomp.c index 7cb99a72f12..d2127fde250 100644 --- a/base/shell/cmd/filecomp.c +++ b/base/shell/cmd/filecomp.c @@ -590,10 +590,20 @@ VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor) /* Start the search for all the files */ GetFullPathName(szBaseWord, MAX_PATH, szSearchPath, NULL); + + /* Got a device path? Fallback to the the current dir plus the short path */ + if (szSearchPath[0] == _T('\\') && szSearchPath[1] == _T('\\') && + szSearchPath[2] == _T('.') && szSearchPath[3] == _T('\\')) + { + GetCurrentDirectory(MAX_PATH, szSearchPath); + _tcscat(szSearchPath, _T("\\")); + _tcscat(szSearchPath, szBaseWord); + } + if(StartLength > 0) - { + { _tcscat(szSearchPath,_T("*")); - } + } _tcscpy(LastSearch,szSearchPath); _tcscpy(LastPrefix,szPrefix); } diff --git a/base/shell/explorer-new/explorer.c b/base/shell/explorer-new/explorer.c index 9c31f33a0fe..8716edc021f 100644 --- a/base/shell/explorer-new/explorer.c +++ b/base/shell/explorer-new/explorer.c @@ -284,7 +284,9 @@ _tWinMain(IN HINSTANCE hInstance, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkExplorer) != ERROR_SUCCESS) { - /* FIXME - display error */ + TCHAR Message[256]; + LoadString(hInstance, IDS_STARTUP_ERROR, Message, 256); + MessageBox(NULL, Message, NULL, MB_ICONERROR); return 1; } diff --git a/base/shell/explorer-new/lang/bg-BG.rc b/base/shell/explorer-new/lang/bg-BG.rc index 482ae13cede..f4c08db2f04 100644 --- a/base/shell/explorer-new/lang/bg-BG.rc +++ b/base/shell/explorer-new/lang/bg-BG.rc @@ -121,6 +121,7 @@ BEGIN IDS_PROPERTIES "&Ńâîéńňâŕ" IDS_OPEN_ALL_USERS "&Îňâŕđ˙íĺ íŕ âńč÷ęč ďîňđĺáčňĺëč" IDS_EXPLORE_ALL_USERS "&Đŕçëčńňâŕíĺ íŕ âńč÷ęč ďîňđĺáčňĺëč" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/cs-CZ.rc b/base/shell/explorer-new/lang/cs-CZ.rc index c82c31a89a0..5273c548ff1 100644 --- a/base/shell/explorer-new/lang/cs-CZ.rc +++ b/base/shell/explorer-new/lang/cs-CZ.rc @@ -126,6 +126,7 @@ BEGIN IDS_PROPERTIES "Vl&astnosti" IDS_OPEN_ALL_USERS "Ote&vřít složku All Users" IDS_EXPLORE_ALL_USERS "Pro&cházet složku All Users" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/de-DE.rc b/base/shell/explorer-new/lang/de-DE.rc index 80aefc0c32a..1173c3ffd90 100644 --- a/base/shell/explorer-new/lang/de-DE.rc +++ b/base/shell/explorer-new/lang/de-DE.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "E&igenschaften" IDS_OPEN_ALL_USERS "Öffnen (&Alle Benutzer)" IDS_EXPLORE_ALL_USERS "Explorer (A&lle Benutzer)" + IDS_STARTUP_ERROR "Das System kann den Explorer nicht starten, weil die Registrierung nicht verfügbar bzw. fehlerhaft ist." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/en-US.rc b/base/shell/explorer-new/lang/en-US.rc index 9e1d6876fde..c98a1face25 100644 --- a/base/shell/explorer-new/lang/en-US.rc +++ b/base/shell/explorer-new/lang/en-US.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "P&roperties" IDS_OPEN_ALL_USERS "O&pen All Users" IDS_EXPLORE_ALL_USERS "E&xplore All Users" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/es-ES.rc b/base/shell/explorer-new/lang/es-ES.rc index b0dcd7ef349..86e83e4ebf1 100644 --- a/base/shell/explorer-new/lang/es-ES.rc +++ b/base/shell/explorer-new/lang/es-ES.rc @@ -129,6 +129,7 @@ BEGIN IDS_PROPERTIES "P&ropiedades" IDS_OPEN_ALL_USERS "A&brir todos los usuarios" IDS_EXPLORE_ALL_USERS "E&xplorar todos los usuarios" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/fr-FR.rc b/base/shell/explorer-new/lang/fr-FR.rc index 57587e9882d..35227391c08 100644 --- a/base/shell/explorer-new/lang/fr-FR.rc +++ b/base/shell/explorer-new/lang/fr-FR.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "P&ropriétés" IDS_OPEN_ALL_USERS "Ouvrir tous les utilisateurs" IDS_EXPLORE_ALL_USERS "E&xplorer tous les utilisateurs" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/it-IT.rc b/base/shell/explorer-new/lang/it-IT.rc index 443c32d624e..eaf2c0b9328 100644 --- a/base/shell/explorer-new/lang/it-IT.rc +++ b/base/shell/explorer-new/lang/it-IT.rc @@ -78,11 +78,11 @@ BEGIN LTEXT "This menu style gives you easy access to your folders, favorite programs, and search.", IDC_STATIC, 20,17,150,24, WS_DISABLED PUSHBUTTON "&Personalizzare...", IDC_TASKBARPROP_STARTMENUCUST, 192,4,53,14, WS_DISABLED AUTORADIOBUTTON "Menů avvio &classico", IDC_TASKBARPROP_STARTMENUCLASSIC, 7,47,105,10, WS_DISABLED - LTEXT "This menu style gives you the classic look and functionality",-1,20,57,150,24, WS_DISABLED - PUSHBUTTON "&Customize...", IDC_TASKBARPROP_STARTMENUCLASSICCUST, 192,44,53,14, WS_DISABLED + LTEXT "Questo stile di menů ha funzionalitŕ e aspetto classici",-1,20,57,150,24, WS_DISABLED + PUSHBUTTON "&Personalizza...", IDC_TASKBARPROP_STARTMENUCLASSICCUST, 192,44,53,14, WS_DISABLED GROUPBOX "Privacy",IDC_STATIC, 7,100,238,42 - AUTOCHECKBOX "Store and display a list of recently opened &files", IDC_TASKBARPROP_RECENTFILES, 14,114,224,10, WS_DISABLED - AUTOCHECKBOX "Store and display a list of recently opened &programs",IDC_TASKBARPROP_RECENTFOLDERS, 14,128,224,10, WS_DISABLED + AUTOCHECKBOX "Memorizza e mostra un elenco di &file aperti di recente", IDC_TASKBARPROP_RECENTFILES, 14,114,224,10, WS_DISABLED + AUTOCHECKBOX "Memorizza e mostra un elenco di &programmi aperti di recente",IDC_TASKBARPROP_RECENTFOLDERS, 14,128,224,10, WS_DISABLED END IDD_TASKBARPROP_NOTIFICATION DIALOGEX 0, 0, 252, 218 @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "&Proprietŕ" IDS_OPEN_ALL_USERS "&Apri tutti gli utenti" IDS_EXPLORE_ALL_USERS "&Esplora tutti gli utenti" + IDS_STARTUP_ERROR "Impossibile avviare explorer perché il registro č danneggiato o non disponibile." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/ja-JP.rc b/base/shell/explorer-new/lang/ja-JP.rc index 5084e2c79b2..66b55a294a9 100644 --- a/base/shell/explorer-new/lang/ja-JP.rc +++ b/base/shell/explorer-new/lang/ja-JP.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "vŤpeB(&R)" IDS_OPEN_ALL_USERS "ŠJ‚­ - All Users(&P)" IDS_EXPLORE_ALL_USERS "GNXvŤ[‰ - All Users(&E)" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/ko-KR.rc b/base/shell/explorer-new/lang/ko-KR.rc index 0232ae1d59b..adbafd39641 100644 --- a/base/shell/explorer-new/lang/ko-KR.rc +++ b/base/shell/explorer-new/lang/ko-KR.rc @@ -125,6 +125,7 @@ BEGIN IDS_PROPERTIES "ĽÓĽş(&R)" IDS_OPEN_ALL_USERS "ż­±â - All Users(&P)" IDS_EXPLORE_ALL_USERS "Ĺ˝»ö - All Users(&X)" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/lt-LT.rc b/base/shell/explorer-new/lang/lt-LT.rc index 5c3c0c69efe..b0dd8e57f62 100644 --- a/base/shell/explorer-new/lang/lt-LT.rc +++ b/base/shell/explorer-new/lang/lt-LT.rc @@ -124,6 +124,7 @@ BEGIN IDS_PROPERTIES "&Parametrai" IDS_OPEN_ALL_USERS "&Atverti visus vartotojus" IDS_EXPLORE_ALL_USERS "&Narđyti visus vartotojus" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/nl-NL.rc b/base/shell/explorer-new/lang/nl-NL.rc index 3dcf5183a7e..135956e86c2 100644 --- a/base/shell/explorer-new/lang/nl-NL.rc +++ b/base/shell/explorer-new/lang/nl-NL.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "&Eigenschappen" IDS_OPEN_ALL_USERS "&Alle Gebruikers weergeven" IDS_EXPLORE_ALL_USERS "Alle Gebruikers V&erkennen" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/no-NO.rc b/base/shell/explorer-new/lang/no-NO.rc index 583fa140de8..d06d1aaf3f2 100644 --- a/base/shell/explorer-new/lang/no-NO.rc +++ b/base/shell/explorer-new/lang/no-NO.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "E&genskaper" IDS_OPEN_ALL_USERS "Ĺ&pne alle brukere" IDS_EXPLORE_ALL_USERS "U&tforsk alle brukere" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/pl-PL.rc b/base/shell/explorer-new/lang/pl-PL.rc index 22a67438dfa..7b8e9de9cb6 100644 --- a/base/shell/explorer-new/lang/pl-PL.rc +++ b/base/shell/explorer-new/lang/pl-PL.rc @@ -123,6 +123,7 @@ BEGIN IDS_PROPERTIES "Właś&ciwości" IDS_OPEN_ALL_USERS "&Otwórz - wszyscy użytkownicy" IDS_EXPLORE_ALL_USERS "&Eksploruj - wszyscy użytkownicy" + IDS_STARTUP_ERROR "System nie może uruchomić eksploratora ponieważ rejestr jest niedostępny lub uszkodzony." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/ro-RO.rc b/base/shell/explorer-new/lang/ro-RO.rc index f18c0a8f57e..f583672499c 100644 --- a/base/shell/explorer-new/lang/ro-RO.rc +++ b/base/shell/explorer-new/lang/ro-RO.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "P&roprietăţi" IDS_OPEN_ALL_USERS "Deschidere& Toţi Utilizatorii" IDS_EXPLORE_ALL_USERS "E&xplorare Toţi Utilizatorii" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/ru-RU.rc b/base/shell/explorer-new/lang/ru-RU.rc index c5d54139dc4..7a21b150a74 100644 --- a/base/shell/explorer-new/lang/ru-RU.rc +++ b/base/shell/explorer-new/lang/ru-RU.rc @@ -122,6 +122,7 @@ BEGIN IDS_PROPERTIES "&Ńâîéńňâŕ" IDS_OPEN_ALL_USERS "&Âńĺ ďîëüçîâŕňĺëč" IDS_EXPLORE_ALL_USERS "&Îáçîđ Âńĺő ďîëüçîâŕňĺëĺé" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/sk-SK.rc b/base/shell/explorer-new/lang/sk-SK.rc index 8cd7c5b9aca..c6329c7e695 100644 --- a/base/shell/explorer-new/lang/sk-SK.rc +++ b/base/shell/explorer-new/lang/sk-SK.rc @@ -120,6 +120,7 @@ BEGIN IDS_PROPERTIES "Vl&astnosti" IDS_OPEN_ALL_USERS "&Otvoriť profil All Users" IDS_EXPLORE_ALL_USERS "&Preskúmať profil All Users" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/lang/uk-UA.rc b/base/shell/explorer-new/lang/uk-UA.rc index d02ee30f9e2..65462be70a4 100644 --- a/base/shell/explorer-new/lang/uk-UA.rc +++ b/base/shell/explorer-new/lang/uk-UA.rc @@ -128,6 +128,7 @@ BEGIN IDS_PROPERTIES "Â&ëŕńňčâîńňł" IDS_OPEN_ALL_USERS "&Âńł ęîđčńňóâŕ÷ł" IDS_EXPLORE_ALL_USERS "&Îăë˙ä âńłő ęîđčńňóâŕ÷łâ" + IDS_STARTUP_ERROR "The system cannot start explorer because the registry is corrupted or unavailable." END STRINGTABLE DISCARDABLE diff --git a/base/shell/explorer-new/resource.h b/base/shell/explorer-new/resource.h index 0ab9222f778..dbdf9c1bef9 100644 --- a/base/shell/explorer-new/resource.h +++ b/base/shell/explorer-new/resource.h @@ -8,6 +8,7 @@ #define IDS_PROPERTIES 102 #define IDS_OPEN_ALL_USERS 103 #define IDS_EXPLORE_ALL_USERS 104 +#define IDS_STARTUP_ERROR 105 #define IDC_STARTBTN 304 diff --git a/base/system/format/format.c b/base/system/format/format.c index ba9f42b3a05..4eae18bb614 100755 --- a/base/system/format/format.c +++ b/base/system/format/format.c @@ -185,7 +185,7 @@ FormatExCallback ( if( *status == FALSE ) { LoadString( GetModuleHandle(NULL), STRING_FORMAT_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); Error = TRUE; } break; @@ -204,7 +204,7 @@ FormatExCallback ( case STRUCTUREPROGRESS: case CLUSTERSIZETOOSMALL: LoadString( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); return FALSE; } return TRUE; @@ -320,7 +320,7 @@ _tmain(int argc, TCHAR *argv[]) // if( !LoadFMIFSEntryPoints()) { LoadString( GetModuleHandle(NULL), STRING_FMIFS_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); return -1; } @@ -422,7 +422,7 @@ _tmain(int argc, TCHAR *argv[]) break; } LoadString( GetModuleHandle(NULL), STRING_ERROR_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); } } @@ -471,7 +471,7 @@ _tmain(int argc, TCHAR *argv[]) ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); } LoadString( GetModuleHandle(NULL), STRING_CREATE_FSYS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); } // @@ -489,7 +489,7 @@ _tmain(int argc, TCHAR *argv[]) #endif if( Error ) return -1; LoadString( GetModuleHandle(NULL), STRING_FMT_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); // // Enable compression if desired @@ -504,7 +504,7 @@ _tmain(int argc, TCHAR *argv[]) #endif LoadString( GetModuleHandle(NULL), STRING_VOL_COMPRESS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); } } @@ -514,7 +514,7 @@ _tmain(int argc, TCHAR *argv[]) if( !GotALabel ) { LoadString( GetModuleHandle(NULL), STRING_ENTER_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); - _tprintf(szMsg); + _tprintf("%s", szMsg); _fgetts( input, sizeof(LabelString)/2, stdin ); input[ _tcslen(input)-1] = 0; diff --git a/base/system/smss/initenv.c b/base/system/smss/initenv.c index 66a0f49ec7f..24ccc3bb5c4 100644 --- a/base/system/smss/initenv.c +++ b/base/system/smss/initenv.c @@ -29,7 +29,7 @@ SmCreateEnvironment(VOID) static NTSTATUS SmpSetEnvironmentVariable(IN PVOID Context, IN PWSTR ValueName, - IN PVOID ValueData) + IN PWSTR ValueData) { UNICODE_STRING EnvVariable; UNICODE_STRING EnvValue; @@ -37,7 +37,7 @@ SmpSetEnvironmentVariable(IN PVOID Context, RtlInitUnicodeString(&EnvVariable, ValueName); RtlInitUnicodeString(&EnvValue, - (PWSTR)ValueData); + ValueData); return RtlSetEnvironmentVariable(Context, &EnvVariable, &EnvValue); @@ -58,12 +58,226 @@ SmpEnvironmentQueryRoutine(IN PWSTR ValueName, return STATUS_SUCCESS; DPRINT("ValueData '%S'\n", (PWSTR)ValueData); - return SmpSetEnvironmentVariable(Context,ValueName,ValueData); + return SmpSetEnvironmentVariable(Context,ValueName,(PWSTR)ValueData); } NTSTATUS SmSetEnvironmentVariables(VOID) +{ + SYSTEM_BASIC_INFORMATION BasicInformation; + SYSTEM_PROCESSOR_INFORMATION ProcessorInformation; + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; + UNICODE_STRING Identifier; + UNICODE_STRING VendorIdentifier; + WCHAR Buffer[256]; + UNICODE_STRING EnvironmentKeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE EnvironmentKey; + UNICODE_STRING VariableName; + PWSTR VariableData; + NTSTATUS Status; + + Status = NtQuerySystemInformation(SystemProcessorInformation, + &ProcessorInformation, + sizeof(SYSTEM_PROCESSOR_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to retrieve system processor information (Status %08lx)", Status); + return Status; + } + + Status = NtQuerySystemInformation(SystemBasicInformation, + &BasicInformation, + sizeof(SYSTEM_BASIC_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to retrieve system basic information (Status %08lx)", Status); + return Status; + } + + RtlInitUnicodeString(&EnvironmentKeyName, + L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Environment"); + InitializeObjectAttributes(&ObjectAttributes, + &EnvironmentKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the system environment key */ + Status = NtOpenKey(&EnvironmentKey, + GENERIC_WRITE, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to open the environment key (Status %08lx)", Status); + return Status; + } + + /* Set the 'NUMBER_OF_PROCESSORS' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"NUMBER_OF_PROCESSORS"); + + swprintf(Buffer, L"%lu", BasicInformation.NumberOfProcessors); + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the NUMBER_OF_PROCESSORS environment variable (Status %08lx)", Status); + goto done; + } + + /* Set the 'OS' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"OS"); + + VariableData = L"ReactOS"; + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + VariableData, + (wcslen(VariableData) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the OS environment variable (Status %08lx)", Status); + goto done; + } + + /* Set the 'PROCESSOR_ARCHITECTURE' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"PROCESSOR_ARCHITECTURE"); + + switch (ProcessorInformation.ProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_INTEL: + VariableData = L"x86"; + break; + + case PROCESSOR_ARCHITECTURE_PPC: + VariableData = L"PPC"; + break; + + case PROCESSOR_ARCHITECTURE_ARM: + VariableData = L"ARM"; + break; + + case PROCESSOR_ARCHITECTURE_AMD64: + VariableData = L"AMD64"; + break; + + default: + VariableData = L"Unknown"; + break; + } + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + VariableData, + (wcslen(VariableData) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the PROCESSOR_ARCHITECTURE environment variable (Status %08lx)", Status); + goto done; + } + + /* Set the 'PROCESSOR_LEVEL' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"PROCESSOR_LEVEL"); + + swprintf(Buffer, L"%lu", ProcessorInformation.ProcessorLevel); + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the PROCESSOR_LEVEL environment variable (Status %08lx)", Status); + goto done; + } + + /* Set the 'PROCESSOR_REVISION' system environment variable */ + RtlInitUnicodeString(&VariableName, + L"PROCESSOR_REVISION"); + + swprintf(Buffer, L"%04x", ProcessorInformation.ProcessorRevision); + + Status = NtSetValueKey(EnvironmentKey, + &VariableName, + 0, + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: Failed to set the PROCESSOR_REVISION environment variable (Status %08lx)", Status); + goto done; + } + +done: + NtClose(EnvironmentKey); + + + /* Set the 'PROCESSOR_IDENTIFIER' system environment variable */ + RtlInitUnicodeString(&Identifier, NULL); + RtlInitUnicodeString(&VendorIdentifier, NULL); + + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); + + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].Name = L"Identifier"; + QueryTable[0].EntryContext = &Identifier; + + QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[1].Name = L"VendorIdentifier"; + QueryTable[1].EntryContext = &VendorIdentifier; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0", + QueryTable, + NULL, + NULL); + if (NT_SUCCESS(Status)) + { + DPRINT("SM: szIdentifier: %wZ\n", &Identifier); + DPRINT("SM: szVendorIdentifier: %wZ\n", &VendorIdentifier); + + swprintf(Buffer, L"%wZ, %wZ", &Identifier, &VendorIdentifier); + + RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, + L"Session Manager\\Environment", + L"PROCESSOR_IDENTIFIER", + REG_SZ, + Buffer, + (wcslen(Buffer) + 1) * sizeof(WCHAR)); + } + + RtlFreeUnicodeString(&Identifier); + RtlFreeUnicodeString(&VendorIdentifier); + + return STATUS_SUCCESS; +} + + +/********************************************************************** + * Set environment variables from registry + */ +NTSTATUS +SmUpdateEnvironment(VOID) { RTL_QUERY_REGISTRY_TABLE QueryTable[2]; WCHAR ValueBuffer[MAX_PATH]; @@ -106,14 +320,4 @@ SmSetEnvironmentVariables(VOID) return Status; } -/********************************************************************** - * Set environment variables from registry - */ -NTSTATUS -SmUpdateEnvironment(VOID) -{ - /* TODO */ - return STATUS_SUCCESS; -} - /* EOF */ diff --git a/base/system/smss/initpage.c b/base/system/smss/initpage.c index 9b889377de6..7ec19985463 100644 --- a/base/system/smss/initpage.c +++ b/base/system/smss/initpage.c @@ -225,34 +225,288 @@ Cleanup: } +static NTSTATUS +SmpGetFreeDiskSpace(IN PWSTR PageFileName, + OUT PLARGE_INTEGER FreeDiskSpaceInMB) +{ + FILE_FS_SIZE_INFORMATION FileFsSize; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE hFile; + UNICODE_STRING NtPathU; + LARGE_INTEGER FreeBytes; + OBJECT_ATTRIBUTES ObjectAttributes; + WCHAR RootPath[5]; + NTSTATUS Status; + + /* + * copy the drive letter, the colon and the slash, + * tack a null on the end + */ + RootPath[0] = PageFileName[0]; + RootPath[1] = L':'; + RootPath[2] = L'\\'; + RootPath[3] = L'\0'; + + DPRINT("Root drive X:\\...\"%S\"\n",RootPath); + + if (!RtlDosPathNameToNtPathName_U(RootPath, + &NtPathU, + NULL, + NULL)) + { + DPRINT1("Invalid path to root of drive\n"); + return STATUS_OBJECT_PATH_INVALID; + } + + InitializeObjectAttributes(&ObjectAttributes, + &NtPathU, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Get a handle to the root to find the free space on the drive */ + Status = NtCreateFile(&hFile, + 0, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + 0, + NULL, + 0); + + RtlFreeHeap(RtlGetProcessHeap(), + 0, + NtPathU.Buffer); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not open a handle to the volume.\n"); + return Status; + } + + Status = NtQueryVolumeInformationFile(hFile, + &IoStatusBlock, + &FileFsSize, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); + + NtClose(hFile); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Querying the volume free space failed!\n"); + return Status; + } + + FreeBytes.QuadPart = FileFsSize.BytesPerSector * + FileFsSize.SectorsPerAllocationUnit * + FileFsSize.AvailableAllocationUnits.QuadPart; + + FreeDiskSpaceInMB->QuadPart = FreeBytes.QuadPart >> 20; + + return STATUS_SUCCESS; +} + + +static NTSTATUS +SmpSetDefaultPageFileData(IN PWSTR PageFileName, + IN PLARGE_INTEGER InitialSizeInMB, + IN PLARGE_INTEGER MaximumSizeInMB) +{ + WCHAR ValueString[MAX_PATH * 2]; + ULONG ValueLength; + + /* Format the value string */ + swprintf(ValueString, + L"%s %I64u %I64u", + PageFileName, + InitialSizeInMB->QuadPart, + MaximumSizeInMB->QuadPart); + + /* + * Append another zero character because it is a multi string value + * (REG_MULTI_SZ) and calculate the total string length. + */ + ValueLength = wcslen(ValueString) + 1; + ValueString[ValueLength] = 0; + ValueLength++; + + /* Write the page file data */ + return RtlWriteRegistryValue(RTL_REGISTRY_CONTROL, + L"\\Session Manager\\Memory Management", + L"PagingFiles", + REG_MULTI_SZ, + ValueString, + ValueLength * sizeof(WCHAR)); +} + + +static NTSTATUS +SmpCreatePageFile(IN PWSTR PageFileName, + IN PLARGE_INTEGER InitialSizeInMB, + IN PLARGE_INTEGER MaximumSizeInMB) +{ + LARGE_INTEGER InitialSize; + LARGE_INTEGER MaximumSize; + UNICODE_STRING FileName; + NTSTATUS Status; + + /* Get the NT path name of the page file */ + if (!RtlDosPathNameToNtPathName_U(PageFileName, + &FileName, + NULL, + NULL)) + { + return STATUS_OBJECT_PATH_INVALID; + } + + /* Convert sizes in megabytes to sizes in bytes */ + InitialSize.QuadPart = InitialSizeInMB->QuadPart << 20; + MaximumSize.QuadPart = MaximumSizeInMB->QuadPart << 20; + + /* Create the pageing file */ + Status = NtCreatePagingFile(&FileName, + &InitialSize, + &MaximumSize, + 0); + if (! NT_SUCCESS(Status)) + { + DPRINT("Creation of paging file %wZ with size %I64d MB failed (status 0x%x)\n", + &FileName, InitialSizeInMB->QuadPart, Status); + } + + /* Release the file name */ + RtlFreeHeap(RtlGetProcessHeap(), + 0, + FileName.Buffer); + + return Status; +} + + +static NTSTATUS +SmpCreateDefaultPagingFile(VOID) +{ + SYSTEM_BASIC_INFORMATION SysBasicInfo; + LARGE_INTEGER MemorySizeInMB; + LARGE_INTEGER FreeDiskSpaceInMB; + LARGE_INTEGER InitialSizeInMB; + LARGE_INTEGER MaximumSizeInMB; + NTSTATUS Status = STATUS_SUCCESS; + WCHAR PageFileName[MAX_PATH]; + + DPRINT("Creating a default paging file\n"); + + Status = NtQuerySystemInformation(SystemBasicInformation, + &SysBasicInfo, + sizeof(SysBasicInfo), + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not query for physical memory size.\n"); + return Status; + } + + DPRINT("PageSize: %d, PhysicalPages: %d, TotalMem: %d\n", + SysBasicInfo.PageSize, + SysBasicInfo.NumberOfPhysicalPages, + (SysBasicInfo.NumberOfPhysicalPages * SysBasicInfo.PageSize) / 1024); + + MemorySizeInMB.QuadPart = (SysBasicInfo.NumberOfPhysicalPages * SysBasicInfo.PageSize) >> 20; + + DPRINT("MemorySize %I64u MB\n", + MemorySizeInMB.QuadPart); + + /* Build the default page file name */ + PageFileName[0] = SharedUserData->NtSystemRoot[0]; + PageFileName[1] = 0; + wcscat(PageFileName, L":\\pagefile.sys"); + + Status = SmpGetFreeDiskSpace(PageFileName, + &FreeDiskSpaceInMB); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + DPRINT("FreeDiskSpace %I64u MB\n", + FreeDiskSpaceInMB.QuadPart); + + InitialSizeInMB.QuadPart = MemorySizeInMB.QuadPart + (MemorySizeInMB.QuadPart / 2); + MaximumSizeInMB.QuadPart = InitialSizeInMB.QuadPart * 2; + + if (InitialSizeInMB.QuadPart > (FreeDiskSpaceInMB.QuadPart / 4)) + { + DPRINT("Inital Size took more then 25%% of free disk space\n"); + + /* + * Set by percentage of free space + * intial is 20%, and max is 25% + */ + InitialSizeInMB.QuadPart = FreeDiskSpaceInMB.QuadPart / 5; + MaximumSizeInMB.QuadPart = FreeDiskSpaceInMB.QuadPart / 4; + + /* The page file is more then a gig, size it down */ + if (InitialSizeInMB.QuadPart > 1024) + { + InitialSizeInMB.QuadPart = 1024; /* 1GB */ + MaximumSizeInMB.QuadPart = 1536; /* 1.5GB */ + } + } + + DPRINT("InitialSize %I64u MB MaximumSize %I64u MB\n", + InitialSizeInMB.QuadPart, + MaximumSizeInMB.QuadPart); + + Status = SmpSetDefaultPageFileData(PageFileName, + &InitialSizeInMB, + &MaximumSizeInMB); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + return SmpCreatePageFile(PageFileName, + &InitialSizeInMB, + &MaximumSizeInMB); +} + + NTSTATUS SmCreatePagingFiles(VOID) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + NTSTATUS Status; - DPRINT("creating system paging files\n"); - /* - * Disable paging file on MiniNT/Live CD. - */ - if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS) + DPRINT("creating system paging files\n"); + + /* Disable paging file on MiniNT/Live CD. */ + if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS) { - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - RtlZeroMemory(&QueryTable, - sizeof(QueryTable)); + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); - QueryTable[0].Name = L"PagingFiles"; - QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine; + QueryTable[0].Name = L"PagingFiles"; + QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; - Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, - L"\\Session Manager\\Memory Management", - QueryTable, - NULL, - NULL); + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, + L"\\Session Manager\\Memory Management", + QueryTable, + NULL, + NULL); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Status = SmpCreateDefaultPagingFile(); + } - return(Status); + return Status; } diff --git a/base/system/winlogon/environment.c b/base/system/winlogon/environment.c index 7a22e494d27..972d09c43bc 100644 --- a/base/system/winlogon/environment.c +++ b/base/system/winlogon/environment.c @@ -19,25 +19,42 @@ WINE_DEFAULT_DEBUG_CHANNEL(winlogon); /* GLOBALS ******************************************************************/ -typedef HRESULT (WINAPI *PFSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR); - /* FUNCTIONS ****************************************************************/ static VOID BuildVolatileEnvironment(IN PWLSESSION Session, - IN HKEY hKey) + IN HKEY hKeyCurrentUser) { - HINSTANCE hShell32 = NULL; - PFSHGETFOLDERPATHW pfSHGetFolderPathW = NULL; WCHAR szPath[MAX_PATH + 1]; - WCHAR szExpandedPath[MAX_PATH + 1]; LPCWSTR wstr; SIZE_T size; WCHAR szEnvKey[MAX_PATH]; WCHAR szEnvValue[1024]; SIZE_T length; LPWSTR eqptr, endptr; + DWORD dwDisp; + LONG lError; + HKEY hKeyVolatileEnv; + HKEY hKeyShellFolders; + DWORD dwType; + DWORD dwSize; + + /* Create the 'Volatile Environment' key */ + lError = RegCreateKeyExW(hKeyCurrentUser, + L"Volatile Environment", + 0, + NULL, + REG_OPTION_VOLATILE, + KEY_WRITE, + NULL, + &hKeyVolatileEnv, + &dwDisp); + if (lError != ERROR_SUCCESS) + { + WARN("WL: RegCreateKeyExW() failed to create the volatile environment key (Error: %ld)\n", lError); + return; + } /* Parse the environment variables and add them to the volatile environment key */ if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 && @@ -68,7 +85,7 @@ BuildVolatileEnvironment(IN PWLSESSION Session, eqptr++; wcscpy(szEnvValue, eqptr); - RegSetValueExW(hKey, + RegSetValueExW(hKeyVolatileEnv, szEnvKey, 0, REG_SZ, @@ -80,50 +97,44 @@ BuildVolatileEnvironment(IN PWLSESSION Session, } } - /* Load shell32.dll and call SHGetFolderPathW to get the users appdata folder path */ - hShell32 = LoadLibraryW(L"shell32.dll"); - if (hShell32 != NULL) + /* Set the 'APPDATA' environment variable */ + lError = RegOpenKeyExW(hKeyCurrentUser, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, + KEY_READ, + &hKeyShellFolders); + if (lError == ERROR_SUCCESS) { - pfSHGetFolderPathW = (PFSHGETFOLDERPATHW)GetProcAddress(hShell32, - "SHGetFolderPathW"); - if (pfSHGetFolderPathW != NULL) + dwSize = (MAX_PATH + 1) * sizeof(WCHAR); + lError = RegQueryValueExW(hKeyShellFolders, + L"AppData", + NULL, + &dwType, + (LPBYTE)szPath, + &dwSize); + if (lError == ERROR_SUCCESS) { - if (pfSHGetFolderPathW(NULL, - CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, - Session->UserToken, - 0, - szPath) == S_OK) - { - /* FIXME: Expand %USERPROFILE% here. SHGetFolderPathW should do it for us. See Bug #5372.*/ - TRACE("APPDATA path: %S\n", szPath); - ExpandEnvironmentStringsForUserW(Session->UserToken, - szPath, - szExpandedPath, - MAX_PATH); - - /* Add the appdata folder path to the users volatile environment key */ - TRACE("APPDATA expanded path: %S\n", szExpandedPath); - RegSetValueExW(hKey, - L"APPDATA", - 0, - REG_SZ, - (LPBYTE)szExpandedPath, - (wcslen(szExpandedPath) + 1) * sizeof(WCHAR)); - } + TRACE("APPDATA path: %S\n", szPath); + RegSetValueExW(hKeyVolatileEnv, + L"APPDATA", + 0, + REG_SZ, + (LPBYTE)szPath, + (wcslen(szPath) + 1) * sizeof(WCHAR)); } - FreeLibrary(hShell32); + RegCloseKey(hKeyShellFolders); } + + RegCloseKey(hKeyVolatileEnv); } BOOL CreateUserEnvironment(IN PWLSESSION Session) { - HKEY hKey; - DWORD dwDisp; - LONG lError; HKEY hKeyCurrentUser; + LONG lError; TRACE("WL: CreateUserEnvironment called\n"); @@ -135,28 +146,8 @@ CreateUserEnvironment(IN PWLSESSION Session) &hKeyCurrentUser); if (lError == ERROR_SUCCESS) { - /* Create the 'Volatile Environment' key */ - lError = RegCreateKeyExW(hKeyCurrentUser, - L"Volatile Environment", - 0, - NULL, - REG_OPTION_VOLATILE, - KEY_WRITE, - NULL, - &hKey, - &dwDisp); - if (lError == ERROR_SUCCESS) - { - BuildVolatileEnvironment(Session, - hKey); - - RegCloseKey(hKey); - } - else - { - WARN("WL: RegCreateKeyExW() failed (Error: %ld)\n", lError); - } - + BuildVolatileEnvironment(Session, + hKeyCurrentUser); RegCloseKey(hKeyCurrentUser); } diff --git a/boot/bootdata/hivedef_arm.inf b/boot/bootdata/hivedef_arm.inf index 086ee67f4fa..8d8c48935d1 100644 --- a/boot/bootdata/hivedef_arm.inf +++ b/boot/bootdata/hivedef_arm.inf @@ -1530,8 +1530,7 @@ HKCU,"Control Panel\Accessibility\Keyboard Preference","On",2,"0" ; Internet Explorer HKCU,Software\Wine\MSHTML,"GeckoUrl",,"http://source.winehq.org/winegecko.php" -;HKCU,Software\Wine\MSHTML,"GeckoCabDir",0x00020000,"%SystemRoot%\" -HKCU,Software\Wine\MSHTML,"GeckoCabDir",,"C:\ReactOS\" +HKCU,Software\Wine\MSHTML,"GeckoCabDir",0x00020000,"%SystemRoot%\" ; Sound Schemes HKCU,"AppEvents",,0x00000012 diff --git a/boot/bootdata/hivedef_i386.inf b/boot/bootdata/hivedef_i386.inf index 905f5ef3daf..8fdc4bb0828 100644 Binary files a/boot/bootdata/hivedef_i386.inf and b/boot/bootdata/hivedef_i386.inf differ diff --git a/boot/bootdata/hivesys_arm.inf b/boot/bootdata/hivesys_arm.inf index 277600b23a6..51f2dc8dd63 100644 --- a/boot/bootdata/hivesys_arm.inf +++ b/boot/bootdata/hivesys_arm.inf @@ -754,13 +754,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","UNC",0x0000 ; System environment settings HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","ComSpec",0x00020000,"%SystemRoot%\system32\cmd.exe" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","OS",0x00020000,"ReactOS" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","Path",0x00020000,"%SystemRoot%\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\system32\wbem" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x00020000,"%SystemRoot%" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TEMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TMP",0x00020000,"%SystemDrive%\TEMP" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00020000,".COM;.EXE;.BAT;.CMD" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PROCESSOR_ARCHITECTURE",0x00020000,"x86" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00000000,".COM;.EXE;.BAT;.CMD" ; Known DLLs @@ -785,9 +783,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","version",0x00 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wininet",0x00000000,"wininet.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wldap32",0x00000000,"wldap32.dll" -; Pagefile settings -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","PagingFiles",0x00010000, \ - "C:\pagefile.sys" +; Memory Management +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management",,0x00000012 ; Subsystems HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Debug",0x00020000,"" diff --git a/boot/bootdata/hivesys_i386.inf b/boot/bootdata/hivesys_i386.inf index 3ca06176457..544f51059f3 100644 --- a/boot/bootdata/hivesys_i386.inf +++ b/boot/bootdata/hivesys_i386.inf @@ -901,13 +901,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","UNC",0x0000 ; System environment settings HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","ComSpec",0x00020000,"%SystemRoot%\system32\cmd.exe" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","OS",0x00020000,"ReactOS" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","Path",0x00020000,"%SystemRoot%\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\system32\wbem" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x00020000,"%SystemRoot%" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TEMP",0x00020000,"%SystemDrive%\TEMP" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","TMP",0x00020000,"%SystemDrive%\TEMP" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00020000,".COM;.EXE;.BAT;.CMD" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PROCESSOR_ARCHITECTURE",0x00020000,"x86" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","PATHEXT",0x00000000,".COM;.EXE;.BAT;.CMD" ; Known DLLs @@ -932,9 +930,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","version",0x00 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wininet",0x00000000,"wininet.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","wldap32",0x00000000,"wldap32.dll" -; Pagefile settings -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","PagingFiles",0x00010000, \ - "C:\pagefile.sys" +; Memory Management +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management",,0x00000012 ; Subsystems HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Debug",0x00020000,"" diff --git a/boot/bootdata/packages/reactos.dff b/boot/bootdata/packages/reactos.dff index c76e469d7f2..12db9f8d330 100644 --- a/boot/bootdata/packages/reactos.dff +++ b/boot/bootdata/packages/reactos.dff @@ -756,6 +756,8 @@ modules\rosapps\drivers\green\green.sys 2 o ; Rostests modules\rostests\rosautotest\rosautotest.exe 1 optional +modules\rostests\drivers\kmtest\kmtest.sys 2 optional +modules\rostests\drivers\kmtest\kmtestassist.sys 2 optional modules\rostests\tests\pseh2\pseh2_test.exe 7 optional modules\rostests\winetests\advapi32\advapi32_winetest.exe 7 optional modules\rostests\winetests\advpack\advpack_winetest.exe 7 optional diff --git a/boot/bootdata/txtsetup.sif b/boot/bootdata/txtsetup.sif index 35f1c761937..c822c2fbc3e 100644 --- a/boot/bootdata/txtsetup.sif +++ b/boot/bootdata/txtsetup.sif @@ -11,6 +11,10 @@ Signature = "$ReactOS$" 6 = Fonts 7 = bin +[DiskSpaceRequirements] +; Required free system partition disk space in MB +FreeSysPartDiskSpace=350 + [SourceDisksFiles] acpi.sys=,,,,,,,,,,,,4 uniata.sys=,,,,,,x,,,,,,4 @@ -54,7 +58,7 @@ Cabinet=reactos.cab [SetupData] DefaultPath = \ReactOS OsLoadOptions = "/NOGUIBOOT /NODEBUG" -DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1" +DbgOsLoadOptions = "/NOGUIBOOT /DEBUGPORT=COM1 /FIRSTCHANCE /KDSERIAL" ;OsLoadOptions = "/NOGUIBOOT /DEBUGPORT=SCREEN" ;OsLoadOptions = "/NOGUIBOOT /DEBUGPORT=BOCHS" diff --git a/boot/freeldr/freeldr/arch/i386/hardware.c b/boot/freeldr/freeldr/arch/i386/hardware.c index 97577aa020c..f99e26780d6 100644 --- a/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/boot/freeldr/freeldr/arch/i386/hardware.c @@ -433,41 +433,22 @@ static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) ULONGLONG SectorOffset = 0; ULONGLONG SectorCount = 0; PARTITION_TABLE_ENTRY PartitionTableEntry; - GEOMETRY Geometry; - EXTENDED_GEOMETRY ExtGeometry; CHAR FileName[1]; if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition)) return EINVAL; - ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY); - if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size)) + if (DrivePartition == 0xff) { - SectorSize = ExtGeometry.BytesPerSector; - SectorCount = ExtGeometry.Sectors; - } - else if (MachDiskGetDriveGeometry(DriveNumber, &Geometry)) - { - SectorSize = Geometry.BytesPerSector; - SectorCount = Geometry.Sectors; + /* This is a CD-ROM device */ + SectorSize = 2048; } else { - DPRINTM(DPRINT_HWDETECT, "Using legacy sector size detection\n"); - - /* Fall back to legacy detection */ - if (DrivePartition == 0xff) - { - /* This is a CD-ROM device */ - SectorSize = 2048; - } - else - { - /* This is either a floppy disk device (DrivePartition == 0) or - * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but - * it doesn't matter which one because they both have 512 bytes per sector */ - SectorSize = 512; - } + /* This is either a floppy disk device (DrivePartition == 0) or + * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but + * it doesn't matter which one because they both have 512 bytes per sector */ + SectorSize = 512; } if (DrivePartition != 0xff && DrivePartition != 0) diff --git a/boot/freeldr/freeldr/arch/i386/i386disk.c b/boot/freeldr/freeldr/arch/i386/i386disk.c index a1e9877e50e..bcee4538a07 100644 --- a/boot/freeldr/freeldr/arch/i386/i386disk.c +++ b/boot/freeldr/freeldr/arch/i386/i386disk.c @@ -51,10 +51,32 @@ BOOLEAN DiskResetController(ULONG DriveNumber) BOOLEAN DiskInt13ExtensionsSupported(ULONG DriveNumber) { + static ULONG LastDriveNumber = 0xffffffff; + static BOOLEAN LastSupported; REGS RegsIn; REGS RegsOut; - DPRINTM(DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"); + DPRINTM(DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"); + + if (DriveNumber == LastDriveNumber) + { + DPRINTM(DPRINT_DISK, "Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber); + return LastSupported; + } + + // Some BIOSes report that extended disk access functions are not supported + // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping + // with Intel Macs). Therefore we just return TRUE if we're booting from a CD - + // we can assume that all El Torito capable BIOSes support INT 13 extensions. + // We simply detect whether we're booting from CD by checking whether the drive + // number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes. + if (DriveNumber >= 0x8A) + { + LastSupported = TRUE; + return TRUE; + } + + LastDriveNumber = DriveNumber; // IBM/MS INT 13 Extensions - INSTALLATION CHECK // AH = 41h @@ -90,35 +112,27 @@ BOOLEAN DiskInt13ExtensionsSupported(ULONG DriveNumber) if (!INT386_SUCCESS(RegsOut)) { // CF set on error (extensions not supported) + LastSupported = FALSE; return FALSE; } if (RegsOut.w.bx != 0xAA55) { // BX = AA55h if installed + LastSupported = FALSE; return FALSE; } - // Note: - // The original check is too strict because some BIOSes report that - // extended disk access functions are not suported when booting - // from a CD (e.g. Phoenix BIOS v6.00PG). Argh! -#if 0 if (!(RegsOut.w.cx & 0x0001)) { // CX = API subset support bitmap // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - return FALSE; - } -#endif - - // Use this relaxed check instead - if (RegsOut.w.cx == 0x0000) - { - // CX = API subset support bitmap + DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber); + LastSupported = FALSE; return FALSE; } + LastSupported = TRUE; return TRUE; } @@ -135,6 +149,9 @@ BOOLEAN DiskGetExtendedDriveParameters(ULONG DriveNumber, PVOID Buffer, USHORT B DPRINTM(DPRINT_DISK, "DiskGetExtendedDriveParameters()\n"); + if (!DiskInt13ExtensionsSupported(DriveNumber)) + return FALSE; + // Initialize transfer buffer *Ptr = BufferSize; diff --git a/boot/freeldr/freeldr/arch/i386/pcdisk.c b/boot/freeldr/freeldr/arch/i386/pcdisk.c index c0eeb0b7d41..304a8670107 100644 --- a/boot/freeldr/freeldr/arch/i386/pcdisk.c +++ b/boot/freeldr/freeldr/arch/i386/pcdisk.c @@ -264,93 +264,6 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(ULONG DriveNumber, ULONGLONG SectorNu return TRUE; } -static BOOLEAN PcDiskInt13ExtensionsSupported(ULONG DriveNumber) -{ - static ULONG LastDriveNumber = 0xffffffff; - static BOOLEAN LastSupported; - REGS RegsIn; - REGS RegsOut; - - DPRINTM(DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"); - - if (DriveNumber == LastDriveNumber) - { - DPRINTM(DPRINT_DISK, "Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber); - return LastSupported; - } - - // Some BIOSes report that extended disk access functions are not supported - // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping - // with Intel Macs). Therefore we just return TRUE if we're booting from a CD - - // we can assume that all El Torito capable BIOSes support INT 13 extensions. - // We simply detect whether we're booting from CD by checking whether the drive - // number is >= 0x90. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes. - if (DriveNumber >= 0x90) - { - LastSupported = TRUE; - return TRUE; - } - - LastDriveNumber = DriveNumber; - - // IBM/MS INT 13 Extensions - INSTALLATION CHECK - // AH = 41h - // BX = 55AAh - // DL = drive (80h-FFh) - // Return: - // CF set on error (extensions not supported) - // AH = 01h (invalid function) - // CF clear if successful - // BX = AA55h if installed - // AH = major version of extensions - // 01h = 1.x - // 20h = 2.0 / EDD-1.0 - // 21h = 2.1 / EDD-1.1 - // 30h = EDD-3.0 - // AL = internal use - // CX = API subset support bitmap - // DH = extension version (v2.0+ ??? -- not present in 1.x) - // - // Bitfields for IBM/MS INT 13 Extensions API support bitmap - // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported - // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported - // extended drive parameter table is valid - // Bits 3-15 reserved - RegsIn.b.ah = 0x41; - RegsIn.w.bx = 0x55AA; - RegsIn.b.dl = DriveNumber; - - // Reset the disk controller - Int386(0x13, &RegsIn, &RegsOut); - - if (!INT386_SUCCESS(RegsOut)) - { - // CF set on error (extensions not supported) - LastSupported = FALSE; - return FALSE; - } - - if (RegsOut.w.bx != 0xAA55) - { - // BX = AA55h if installed - LastSupported = FALSE; - return FALSE; - } - - if (!(RegsOut.w.cx & 0x0001)) - { - // CX = API subset support bitmap - // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - printf("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber); - LastSupported = FALSE; - return FALSE; - } - - LastSupported = TRUE; - return TRUE; -} - BOOLEAN PcDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) { @@ -361,9 +274,9 @@ BOOLEAN PcDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULON // If so then check to see if Int13 extensions work // If they do then use them, otherwise default back to BIOS calls // - if ((DriveNumber >= 0x80) && PcDiskInt13ExtensionsSupported(DriveNumber)) + if ((DriveNumber >= 0x80) && DiskInt13ExtensionsSupported(DriveNumber)) { - DPRINTM(DPRINT_DISK, "Using Int 13 Extensions for read. PcDiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, PcDiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"); + DPRINTM(DPRINT_DISK, "Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, DiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"); // // LBA is easy, nothing to calculate diff --git a/boot/freeldr/freeldr/fs/ntfs.c b/boot/freeldr/freeldr/fs/ntfs.c index 830e3ade042..aff3bfaa339 100644 --- a/boot/freeldr/freeldr/fs/ntfs.c +++ b/boot/freeldr/freeldr/fs/ntfs.c @@ -1,6 +1,7 @@ /* * FreeLoader NTFS support * Copyright (C) 2004 Filip Navara + * Copyright (C) 2009-2010 Hervé Poussineau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +38,7 @@ typedef struct _NTFS_VOLUME_INFO /* FIXME: MFTContext is never freed. */ PNTFS_ATTR_CONTEXT MFTContext; ULONG DeviceId; + PUCHAR TemporarySector; } NTFS_VOLUME_INFO; PNTFS_VOLUME_INFO NtfsVolumes[MAX_FDS]; @@ -147,10 +149,17 @@ static BOOLEAN NtfsDiskRead(PNTFS_VOLUME_INFO Volume, ULONGLONG Offset, ULONGLON ret = ArcSeek(Volume->DeviceId, &Position, SeekAbsolute); if (ret != ESUCCESS) return FALSE; - ReadLength = min(Length, Volume->BootSector.BytesPerSector - (Offset % Volume->BootSector.BytesPerSector)); - ret = ArcRead(Volume->DeviceId, Buffer, ReadLength, &Count); - if (ret != ESUCCESS || Count != ReadLength) + ret = ArcRead(Volume->DeviceId, Volume->TemporarySector, Volume->BootSector.BytesPerSector, &Count); + if (ret != ESUCCESS || Count != Volume->BootSector.BytesPerSector) return FALSE; + ReadLength = min(Length, Volume->BootSector.BytesPerSector - (Offset % Volume->BootSector.BytesPerSector)); + + // + // Copy interesting data + // + RtlCopyMemory(Buffer, + &Volume->TemporarySector[Offset % Volume->BootSector.BytesPerSector], + ReadLength); // // Move to unfilled buffer part @@ -232,7 +241,9 @@ static ULONGLONG NtfsReadAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_CONTEXT AlreadyRead = 0; - if(Context->CacheRunOffset <= Offset && Offset < Context->CacheRunOffset + Context->CacheRunLength * Volume->ClusterSize) + // FIXME: Cache seems to be non-working. Disable it for now + //if(Context->CacheRunOffset <= Offset && Offset < Context->CacheRunOffset + Context->CacheRunLength * Volume->ClusterSize) + if (0) { DataRun = Context->CacheRun; LastLCN = Context->CacheRunLastLCN; @@ -790,6 +801,7 @@ LONG NtfsOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) return ENOENT; } + FsSetDeviceSpecific(*FileId, FileHandle); return ESUCCESS; } @@ -930,6 +942,18 @@ const DEVVTBL* NtfsMount(ULONG DeviceId) return NULL; } + // + // Keep room to read partial sectors + // + Volume->TemporarySector = MmHeapAlloc(Volume->BootSector.BytesPerSector); + if (!Volume->TemporarySector) + { + FileSystemError("Failed to allocate memory."); + MmHeapFree(Volume->MasterFileTable); + MmHeapFree(Volume); + return NULL; + } + // // Keep device id // diff --git a/boot/freeldr/freeldr/include/options.h b/boot/freeldr/freeldr/include/options.h index 124b64e2326..b00d9f58daf 100644 --- a/boot/freeldr/freeldr/include/options.h +++ b/boot/freeldr/freeldr/include/options.h @@ -20,3 +20,4 @@ #pragma once VOID DoOptionsMenu(VOID); +VOID AppendBootTimeOptions(PCHAR BootOptions); diff --git a/boot/freeldr/freeldr/options.c b/boot/freeldr/freeldr/options.c index 4dabc89c6f4..5b64b46a077 100644 --- a/boot/freeldr/freeldr/options.c +++ b/boot/freeldr/freeldr/options.c @@ -69,6 +69,15 @@ enum OptionMenuItems ULONG OptionsMenuItemCount = sizeof(OptionsMenuList) / sizeof(OptionsMenuList[0]); +BOOLEAN SafeMode = FALSE; +BOOLEAN SafeModeWithNetworking = FALSE; +BOOLEAN SafeModeWithCommandPrompt = FALSE; +BOOLEAN BootLogging = FALSE; +BOOLEAN VgaMode = FALSE; +BOOLEAN LastKnownGoodConfiguration = FALSE; +BOOLEAN DirectoryServicesRepairMode = FALSE; +BOOLEAN DebuggingMode = FALSE; + VOID DoOptionsMenu(VOID) { ULONG SelectedMenuItem; @@ -85,22 +94,33 @@ VOID DoOptionsMenu(VOID) switch (SelectedMenuItem) { case SAFE_MODE: + SafeMode = TRUE; + BootLogging = TRUE; break; case SAFE_MODE_WITH_NETWORKING: + SafeModeWithNetworking = TRUE; + BootLogging = TRUE; break; case SAFE_MODE_WITH_COMMAND_PROMPT: + SafeModeWithCommandPrompt = TRUE; + BootLogging = TRUE; break; //case SEPARATOR1: // break; case ENABLE_BOOT_LOGGING: + BootLogging = TRUE; break; case ENABLE_VGA_MODE: + VgaMode = TRUE; break; case LAST_KNOWN_GOOD_CONFIGURATION: + LastKnownGoodConfiguration = TRUE; break; case DIRECTORY_SERVICES_RESTORE_MODE: + DirectoryServicesRepairMode = TRUE; break; case DEBUGGING_MODE: + DebuggingMode = TRUE; break; //case SEPARATOR2: // break; @@ -117,3 +137,29 @@ VOID DoOptionsMenu(VOID) } } +VOID AppendBootTimeOptions(PCHAR BootOptions) +{ + if (SafeMode) + strcat(BootOptions, " /SAFEBOOT:MINIMAL /SOS"); //FIXME: NOGUIBOOT should also be specified + + if (SafeModeWithNetworking) + strcat(BootOptions, " /SAFEBOOT:NETWORK /SOS"); //FIXME: NOGUIBOOT should also be specified + + if (SafeModeWithCommandPrompt) + strcat(BootOptions, " /SAFEBOOT:MINIMAL(ALTERNATESHELL) /SOS"); //FIXME: NOGUIBOOT should also be specified + + if (BootLogging) + strcat(BootOptions, " /BOOTLOG"); + + if (VgaMode) + strcat(BootOptions, " /BASEVIDEO"); + + if (LastKnownGoodConfiguration) + DbgPrint("Last known good configuration is not supported yet!\n"); + + if (DirectoryServicesRepairMode) + strcat(BootOptions, " /SAFEBOOT:DSREPAIR /SOS"); + + if (DebuggingMode) + strcat(BootOptions, " /DEBUG"); +} diff --git a/boot/freeldr/freeldr/reactos/reactos.c b/boot/freeldr/freeldr/reactos/reactos.c index 81b654b84b9..22f3771b28b 100644 --- a/boot/freeldr/freeldr/reactos/reactos.c +++ b/boot/freeldr/freeldr/reactos/reactos.c @@ -606,6 +606,11 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) // if (IniReadSettingByName(SectionId, "Options", value, sizeof(value))) { + // + // Append boot-time options + // + AppendBootTimeOptions(value); + // // Check if a ramdisk file was given // diff --git a/boot/freeldr/freeldr/windows/winldr.c b/boot/freeldr/freeldr/windows/winldr.c index d130472ebae..c068517dd2b 100644 --- a/boot/freeldr/freeldr/windows/winldr.c +++ b/boot/freeldr/freeldr/windows/winldr.c @@ -475,6 +475,9 @@ LoadAndBootWindows(PCSTR OperatingSystemName, DPRINTM(DPRINT_WINDOWS,"BootOptions: '%s'\n", BootOptions); } + /* Append boot-time options */ + AppendBootTimeOptions(BootOptions); + // // Check if a ramdisk file was given // diff --git a/dll/3rdparty/libjpeg/libjpeg.rbuild b/dll/3rdparty/libjpeg/libjpeg.rbuild index 990e595377f..9749f7ab35e 100644 --- a/dll/3rdparty/libjpeg/libjpeg.rbuild +++ b/dll/3rdparty/libjpeg/libjpeg.rbuild @@ -1,11 +1,11 @@ - -Wno-main + mainptr . jcapimin.c jcapistd.c diff --git a/dll/cpl/desk/screensaver.c b/dll/cpl/desk/screensaver.c index c24cf78620c..00ce09568b2 100644 --- a/dll/cpl/desk/screensaver.c +++ b/dll/cpl/desk/screensaver.c @@ -147,33 +147,32 @@ static BOOL WaitForSettingsDialog(HWND hwndDlg, HANDLE hProcess) { + DWORD dwResult; + MSG msg; + while (TRUE) { - DWORD Ret; - MSG msg; - - while (PeekMessage(&msg, - NULL, - 0, - 0, - PM_REMOVE)) + dwResult = MsgWaitForMultipleObjects(1, + &hProcess, + FALSE, + INFINITE, + QS_ALLINPUT); + if (dwResult == WAIT_OBJECT_0 + 1) { - if (msg.message == WM_QUIT) - return FALSE; - - if (IsDialogMessage(hwndDlg, &msg)) + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); + if (msg.message == WM_QUIT) + { + return FALSE; + } + if (IsDialogMessage(hwndDlg, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } } - - Ret = MsgWaitForMultipleObjects(1, - &hProcess, - FALSE, - INFINITE, - QS_ALLINPUT); - if (Ret == (WAIT_OBJECT_0)) + else { return TRUE; } diff --git a/dll/cpl/intl/lang/cs-CZ.rc b/dll/cpl/intl/lang/cs-CZ.rc index c72579df513..6685326e741 100644 --- a/dll/cpl/intl/lang/cs-CZ.rc +++ b/dll/cpl/intl/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/cpl/intl/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2009-07-16 + * UPDATED: 2010-05-22 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -193,8 +193,8 @@ STRINGTABLE BEGIN IDS_CUSTOMIZE_TITLE "Přizpůsobit místní nastavení" IDS_SPAIN "Španělština (Španělsko)" - IDS_METRIC "Metric" - IDS_IMPERIAL "Imperial" + IDS_METRIC "Metrický" + IDS_IMPERIAL "Imperiální" END STRINGTABLE diff --git a/dll/cpl/intl/lang/it-IT.rc b/dll/cpl/intl/lang/it-IT.rc index ee1513a685c..eaaf6683f05 100644 --- a/dll/cpl/intl/lang/it-IT.rc +++ b/dll/cpl/intl/lang/it-IT.rc @@ -181,7 +181,7 @@ FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Ordinamento", -1, 7, 7, 230, 74 LTEXT "Il metodo di ordinamento definisce come considerare l'ordine di caratteri, parole, file e cartelle.", -1, 14, 17, 220, 25 - LTEXT "Scegliere il metodo di orinamento per il vostro linguaggio:", -1, 14, 37, 220, 22 + LTEXT "Scegliere il metodo di ordinamento per il vostro linguaggio:", -1, 14, 37, 220, 22 COMBOBOX IDC_SORTLIST_COMBO, 14, 56, 217, 83, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL END diff --git a/dll/cpl/intl/lang/pl-PL.rc b/dll/cpl/intl/lang/pl-PL.rc index a80e5dba5da..3b566acdc75 100644 --- a/dll/cpl/intl/lang/pl-PL.rc +++ b/dll/cpl/intl/lang/pl-PL.rc @@ -1,5 +1,5 @@ /* - * translated by Caemyr - Olaf Siejka (Jan, 2008) + * translated by Caemyr - Olaf Siejka (Jan, 2008; May 2010) * Use ReactOS forum PM or IRC to contact me * http://www.reactos.org * IRC: irc.freenode.net #reactos-pl; @@ -195,8 +195,8 @@ STRINGTABLE BEGIN IDS_CUSTOMIZE_TITLE "Dostosuj Ustawienia regionalne" IDS_SPAIN "Hiszpański (Hiszpania)" - IDS_METRIC "Metric" - IDS_IMPERIAL "Imperial" + IDS_METRIC "Metryczne" + IDS_IMPERIAL "Imperialne" END STRINGTABLE diff --git a/dll/cpl/mmsys/lang/de-DE.rc b/dll/cpl/mmsys/lang/de-DE.rc index 81e3d437828..6ddf8ae5a35 100644 --- a/dll/cpl/mmsys/lang/de-DE.rc +++ b/dll/cpl/mmsys/lang/de-DE.rc @@ -36,9 +36,9 @@ BEGIN LTEXT "&Programmereignisse:",-1,8,118,150,17 CONTROL "", IDC_SCHEME_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 8, 130, 230, 60, WS_EX_CLIENTEDGE LTEXT "&Klänge:", IDC_TEXT_SOUND,8,194,80,17, WS_DISABLED - COMBOBOX IDC_SOUND_LIST, 8, 205, 155, 146, CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED - PUSHBUTTON "", IDC_PLAY_SOUND, 168,205,15,15, WS_DISABLED | BS_ICON - PUSHBUTTON "&Durchsuchen...", IDC_BROWSE_SOUND, 188,205,81,15, WS_DISABLED + COMBOBOX IDC_SOUND_LIST, 8, 205, 135, 146, CBS_DROPDOWNLIST | CBS_DISABLENOSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED + PUSHBUTTON "", IDC_PLAY_SOUND, 148,205,15,15, WS_DISABLED | BS_ICON + PUSHBUTTON "&Durchsuchen...", IDC_BROWSE_SOUND, 168,205,70,15, WS_DISABLED END IDD_AUDIO DIALOGEX 0, 0, 246, 228 diff --git a/dll/cpl/mmsys/sounds.c b/dll/cpl/mmsys/sounds.c index be314e181e0..c7ff17187a5 100644 --- a/dll/cpl/mmsys/sounds.c +++ b/dll/cpl/mmsys/sounds.c @@ -718,6 +718,14 @@ LoadSoundFiles(HWND hwndDlg) LRESULT lResult; UINT length; + /* Add no sound listview item */ + if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH)) + { + szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0'; + SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath); + } + + /* Load sound files */ length = GetWindowsDirectoryW(szPath, MAX_PATH); if (length == 0 || length >= MAX_PATH - 9) { @@ -736,11 +744,6 @@ LoadSoundFiles(HWND hwndDlg) { return FALSE; } - if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH)) - { - szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0'; - SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath); - } do { @@ -1054,6 +1057,7 @@ SoundsDlgProc(HWND hwndDlg, ZeroMemory(&item, sizeof(LVITEM)); item.mask = LVIF_PARAM; item.iItem = nm->iItem; + if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item)) { LRESULT lCount, lIndex, lResult; diff --git a/dll/cpl/sysdm/lang/bg-BG.rc b/dll/cpl/sysdm/lang/bg-BG.rc index cd0cca37d03..c358cf4e3e1 100644 --- a/dll/cpl/sysdm/lang/bg-BG.rc +++ b/dll/cpl/sysdm/lang/bg-BG.rc @@ -284,4 +284,9 @@ BEGIN IDS_USERPROFILE_TYPE "Âčä" IDS_USERPROFILE_STATUS "Ńúńňî˙íčĺ" IDS_USERPROFILE_MODIFIED "Čçěĺíĺí" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/cs-CZ.rc b/dll/cpl/sysdm/lang/cs-CZ.rc index 5be033c26d3..2e11444dea1 100644 --- a/dll/cpl/sysdm/lang/cs-CZ.rc +++ b/dll/cpl/sysdm/lang/cs-CZ.rc @@ -289,4 +289,9 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Upraveno" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/da-DK.rc b/dll/cpl/sysdm/lang/da-DK.rc index 4e680cba885..136a1dec301 100644 --- a/dll/cpl/sysdm/lang/da-DK.rc +++ b/dll/cpl/sysdm/lang/da-DK.rc @@ -123,4 +123,9 @@ BEGIN IDS_MINI_DUMP "Minidump(64KB)" IDS_KERNEL_DUMP "Kernel dump" IDS_FULL_DUMP "Complete dump" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/de-DE.rc b/dll/cpl/sysdm/lang/de-DE.rc index 92282242d97..eec7d1eff51 100644 --- a/dll/cpl/sysdm/lang/de-DE.rc +++ b/dll/cpl/sysdm/lang/de-DE.rc @@ -202,7 +202,7 @@ BEGIN LTEXT "", IDC_SPACEAVAIL, 105, 92, 104, 9 LTEXT "&Anfangsgröße (MB):", -1, 22, 118, 70, 9 LTEXT "Ma&ximale Größe (MB):", -1, 22, 131, 75, 9 - AUTORADIOBUTTON "&Benutzerdefinierte Größe", IDC_CUSTOM, 20, 105, 90, 9, WS_GROUP + AUTORADIOBUTTON "&Benutzerdefinierte Größe", IDC_CUSTOM, 20, 105, 95, 9, WS_GROUP AUTORADIOBUTTON "Größe wird vom &System verwaltet", IDC_SYSMANSIZE, 20, 145, 120, 9 AUTORADIOBUTTON "&Keine Auslagerungsdatei", IDC_NOPAGEFILE, 20, 158, 90, 9 EDITTEXT IDC_INITIALSIZE, 100, 114, 44, 13, NOT WS_BORDER, WS_EX_CLIENTEDGE @@ -289,5 +289,10 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Geändert" + IDS_MESSAGEBOXTITLE "Systemsteuerungsoption ""System""" + IDS_WARNINITIALSIZE "Geben Sie einen numerischen Wert für die Anfangsgröße der Auslagerungsdatei an." + IDS_WARNMAXIMUMSIZE "Geben Sie einen numerischen Wert für die Maximalgröße der Auslagerungsdatei an." + IDS_WARNINITIALRANGE "Die Anfangsgröße der Auslagerungsdatei darf nicht kleiner als 2 MB sein und darf den verfügbaren Speicherplatz auf dem gewählten Laufwerk nicht überschreiten." + IDS_WARNMAXIMUMRANGE "Die Maximalgröße der Auslagerungsdatei darf nicht kleiner als die Anfangsgröße sein und darf den verfügbaren Speicherplatz auf dem gewählten Laufwerk nicht überschreiten." IDS_DEVS "\nReactOS Team\n\nProjektkoordinator\n\nAleksey Bragin\n\nEntwicklerteam\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Verantwortliche\n\nColin Finck\nZ98\n\nWebseitenteam\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedienteam\n\nMindflyer\nWierd_W\n\nweiterer Dank geht an\n\nalle Mitwirkenden\nWine Team\n\n" END diff --git a/dll/cpl/sysdm/lang/el-GR.rc b/dll/cpl/sysdm/lang/el-GR.rc index 98ff6946bd1..426438a5853 100644 --- a/dll/cpl/sysdm/lang/el-GR.rc +++ b/dll/cpl/sysdm/lang/el-GR.rc @@ -285,4 +285,9 @@ BEGIN IDS_USERPROFILE_TYPE "Ôýđďň" IDS_USERPROFILE_STATUS "ĘáôÜóôáóç" IDS_USERPROFILE_MODIFIED "ÔńďđďđďéŢčçęĺ" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/en-US.rc b/dll/cpl/sysdm/lang/en-US.rc index 73b8a17d3aa..c1d7fa93eeb 100644 --- a/dll/cpl/sysdm/lang/en-US.rc +++ b/dll/cpl/sysdm/lang/en-US.rc @@ -284,5 +284,10 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Modified" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." IDS_DEVS "\nReactOS Team\n\nProject Coordinator\n\nAleksey Bragin\n\nDevelopment Team\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nfurther thanks go to\n\nall Contributers\nWine Team\n\n" END diff --git a/dll/cpl/sysdm/lang/es-ES.rc b/dll/cpl/sysdm/lang/es-ES.rc index 69e46cfc606..7383919a99b 100644 --- a/dll/cpl/sysdm/lang/es-ES.rc +++ b/dll/cpl/sysdm/lang/es-ES.rc @@ -287,4 +287,9 @@ BEGIN IDS_USERPROFILE_TYPE "Tipo" IDS_USERPROFILE_STATUS "Estado" IDS_USERPROFILE_MODIFIED "Modificado" + IDS_MESSAGEBOXTITLE "Applet de sistema del panel de control" + IDS_WARNINITIALSIZE "Ingresar el tamańo inicial del archivo de paginación." + IDS_WARNMAXIMUMSIZE "Ingresar el tamańo máximo del archivo de paginación." + IDS_WARNINITIALRANGE "El tamańo inicial del archivo de paginación no puede ser inferior a 2 MB y no puede exceder el espacio disponible en la unidad seleccionada." + IDS_WARNMAXIMUMRANGE "El tamańo máximo del archivo de paginación no puede ser inferior al tamańo inicial y no puede exceder el espacio disponible en la unidad seleccionada." END diff --git a/dll/cpl/sysdm/lang/fr-FR.rc b/dll/cpl/sysdm/lang/fr-FR.rc index e649b59beff..17fe2e15d6b 100644 --- a/dll/cpl/sysdm/lang/fr-FR.rc +++ b/dll/cpl/sysdm/lang/fr-FR.rc @@ -287,4 +287,9 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Statut" IDS_USERPROFILE_MODIFIED "Modifié" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/hu-HU.rc b/dll/cpl/sysdm/lang/hu-HU.rc index 9b3a4624d62..1324096ab32 100644 --- a/dll/cpl/sysdm/lang/hu-HU.rc +++ b/dll/cpl/sysdm/lang/hu-HU.rc @@ -126,4 +126,9 @@ BEGIN IDS_MINI_DUMP "Minidump(64KB)" IDS_KERNEL_DUMP "Kernel dump" IDS_FULL_DUMP "Complete dump" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/id-ID.rc b/dll/cpl/sysdm/lang/id-ID.rc index 1025b1f5b6d..6bd09c9f406 100644 --- a/dll/cpl/sysdm/lang/id-ID.rc +++ b/dll/cpl/sysdm/lang/id-ID.rc @@ -281,4 +281,9 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Modified" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/it-IT.rc b/dll/cpl/sysdm/lang/it-IT.rc index 253a4bd1084..0175497f2a9 100644 --- a/dll/cpl/sysdm/lang/it-IT.rc +++ b/dll/cpl/sysdm/lang/it-IT.rc @@ -284,5 +284,10 @@ BEGIN IDS_USERPROFILE_TYPE "Tipo" IDS_USERPROFILE_STATUS "Stato" IDS_USERPROFILE_MODIFIED "Modificato" + IDS_MESSAGEBOXTITLE "Applet di sistema del pannello di controllo" + IDS_WARNINITIALSIZE "Immettere la dimensione iniziale del file di paging." + IDS_WARNMAXIMUMSIZE "Immettere la dimensione massima del file di paging." + IDS_WARNINITIALRANGE "La dimensione iniziale del file di paging non puň essere inferiore a 2 MB e non puň superare lo spazio disponibile nell'unitŕ selezionata." + IDS_WARNMAXIMUMRANGE "La dimensione massima del file di paging non puň essere inferiore a quella iniziale e non puň superare lo spazio disponibile nell'unitŕ selezionata." IDS_DEVS "\nReactOS Team\n\nCoordinatore\n\nAleksey Bragin\n\nGruppo di sviluppo\n\nAleksey Bragin\nAndrew Greenwood\nAndrey Korotaev\nArt Yerkes\nChristoph von Wittich\nColin Finck\nDaniel Reimer\nDmitry Chapyshev\nEric Kohl\nGed Murphy\nGregor Brunmar\nHervé Poussineau\nJames Tabor\nJeffrey Morlan\nJohannes Anderwald\nKJK::Hyperion\nMaarten Bosma\nMagnus Olsen\nMarc Piulachs\nMatthias Kupfer\nMike Nordell\nPeter Ward\nPierre Schweitzer\nSaveliy Tretiakov\nStefan Ginsberg\nSylvain Petreolle\nThomas Blümel\nTimo Kreuzer \n\nAlex Ionescu\nFilip Navara\nGunnar Dalsnes\nMartin Fuchs\nRoyce Mitchell III\nBrandon Turner\nBrian Palmer\nCasper Hornstrup\nDavid Welch\nEmanuele Aliberti\nGé van Geldorp\nGregor Anich\nJason Filby\nJens Collin\nMichael Wirth\nNathan Woods\nRobert Dickenson\nRex Jolliff\nVizzini \n\nRelease Engineers\n\nColin Finck\nZ98\n\nWebsite Team\n\nColin Finck\nJaix Bly\nKlemens Friedl\nZ98\n\nMedia Team\n\nMindflyer\nWierd_W\n\nUlteriori ringraziamenti\n\na tutti i Contributers\nWine Team\n\n" END diff --git a/dll/cpl/sysdm/lang/ja-JP.rc b/dll/cpl/sysdm/lang/ja-JP.rc index 2ce3b7c5f41..7b86e4e0f92 100644 --- a/dll/cpl/sysdm/lang/ja-JP.rc +++ b/dll/cpl/sysdm/lang/ja-JP.rc @@ -284,4 +284,9 @@ BEGIN IDS_USERPROFILE_TYPE "Ží—Ţ" IDS_USERPROFILE_STATUS "Źó‘Ô" IDS_USERPROFILE_MODIFIED "•ĎŤX“ú" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/nl-NL.rc b/dll/cpl/sysdm/lang/nl-NL.rc index 888857b6205..94eca7ef70b 100644 --- a/dll/cpl/sysdm/lang/nl-NL.rc +++ b/dll/cpl/sysdm/lang/nl-NL.rc @@ -125,5 +125,9 @@ BEGIN IDS_MINI_DUMP "Minidump(64KB)" IDS_KERNEL_DUMP "Kernel dump" IDS_FULL_DUMP "Complete dump" - + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/no-NO.rc b/dll/cpl/sysdm/lang/no-NO.rc index 98beebe5b50..4c6d9997b75 100644 --- a/dll/cpl/sysdm/lang/no-NO.rc +++ b/dll/cpl/sysdm/lang/no-NO.rc @@ -283,4 +283,9 @@ BEGIN IDS_USERPROFILE_TYPE "Type" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Modifisert" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/pl-PL.rc b/dll/cpl/sysdm/lang/pl-PL.rc index b138c0afd90..91f7db5ed4c 100644 --- a/dll/cpl/sysdm/lang/pl-PL.rc +++ b/dll/cpl/sysdm/lang/pl-PL.rc @@ -288,4 +288,9 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Stan" IDS_USERPROFILE_MODIFIED "Zmodyfikowano" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/ro-RO.rc b/dll/cpl/sysdm/lang/ro-RO.rc index 7e5de71be46..ea9ea85bf1c 100644 --- a/dll/cpl/sysdm/lang/ro-RO.rc +++ b/dll/cpl/sysdm/lang/ro-RO.rc @@ -1,4 +1,4 @@ -LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL +LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL #pragma code_page(65001) @@ -284,6 +284,11 @@ BEGIN IDS_USERPROFILE_TYPE "Tip" IDS_USERPROFILE_STATUS "Stare" IDS_USERPROFILE_MODIFIED "Modificat" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END #pragma code_page(default) diff --git a/dll/cpl/sysdm/lang/ru-RU.rc b/dll/cpl/sysdm/lang/ru-RU.rc index caaef697bf2..72ecb3cc417 100644 --- a/dll/cpl/sysdm/lang/ru-RU.rc +++ b/dll/cpl/sysdm/lang/ru-RU.rc @@ -282,4 +282,9 @@ BEGIN IDS_USERPROFILE_TYPE "Ňčď" IDS_USERPROFILE_STATUS "Ńîńňî˙íčĺ" IDS_USERPROFILE_MODIFIED "Čçěĺíĺí" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/sk-SK.rc b/dll/cpl/sysdm/lang/sk-SK.rc index 82fbc6035e9..497720ce90d 100644 --- a/dll/cpl/sysdm/lang/sk-SK.rc +++ b/dll/cpl/sysdm/lang/sk-SK.rc @@ -290,4 +290,9 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Stav" IDS_USERPROFILE_MODIFIED "Modifikovaný" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/sv-SE.rc b/dll/cpl/sysdm/lang/sv-SE.rc index c72592cdb89..124bbe935e9 100644 --- a/dll/cpl/sysdm/lang/sv-SE.rc +++ b/dll/cpl/sysdm/lang/sv-SE.rc @@ -284,4 +284,9 @@ BEGIN IDS_USERPROFILE_TYPE "Typ" IDS_USERPROFILE_STATUS "Status" IDS_USERPROFILE_MODIFIED "Ändrad" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/uk-UA.rc b/dll/cpl/sysdm/lang/uk-UA.rc index 651a167d1ea..a92a15d4c0c 100644 --- a/dll/cpl/sysdm/lang/uk-UA.rc +++ b/dll/cpl/sysdm/lang/uk-UA.rc @@ -290,4 +290,9 @@ BEGIN IDS_USERPROFILE_TYPE "Ňčď" IDS_USERPROFILE_STATUS "Ńňŕí" IDS_USERPROFILE_MODIFIED "Çěłíĺíî" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/lang/zh-CN.rc b/dll/cpl/sysdm/lang/zh-CN.rc index 1abbce7477f..0ce9e187dd9 100644 --- a/dll/cpl/sysdm/lang/zh-CN.rc +++ b/dll/cpl/sysdm/lang/zh-CN.rc @@ -287,4 +287,9 @@ BEGIN IDS_USERPROFILE_TYPE "ŔŕĐÍ" IDS_USERPROFILE_STATUS "״̬" IDS_USERPROFILE_MODIFIED "Đ޸Ä" + IDS_MESSAGEBOXTITLE "System control panel applet" + IDS_WARNINITIALSIZE "Enter a numeric value for the initial size of the paging file." + IDS_WARNMAXIMUMSIZE "Enter a numeric value for the maximum size of the paging file." + IDS_WARNINITIALRANGE "The initial size of the paging file must not be smaller than 2 MB and must not exceed the available space on the selected drive." + IDS_WARNMAXIMUMRANGE "The maximum size of the paging file must not be smaller than its initial size and must not exceed the available space on the selected drive." END diff --git a/dll/cpl/sysdm/precomp.h b/dll/cpl/sysdm/precomp.h index 3ef2ee0d259..cf3afd6f62a 100644 --- a/dll/cpl/sysdm/precomp.h +++ b/dll/cpl/sysdm/precomp.h @@ -50,8 +50,9 @@ INT_PTR CALLBACK LicenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM l typedef struct _PAGEFILE { TCHAR szDrive[3]; - INT InitialValue; - INT MaxValue; + INT InitialSize; + INT MaximumSize; + INT FreeSize; BOOL bUsed; } PAGEFILE, *PPAGEFILE; diff --git a/dll/cpl/sysdm/resource.h b/dll/cpl/sysdm/resource.h index f0918a35d9f..885aae6c003 100644 --- a/dll/cpl/sysdm/resource.h +++ b/dll/cpl/sysdm/resource.h @@ -32,6 +32,11 @@ #define IDS_USERPROFILE_STATUS 75 #define IDS_USERPROFILE_MODIFIED 76 +#define IDS_MESSAGEBOXTITLE 77 +#define IDS_WARNINITIALSIZE 78 +#define IDS_WARNMAXIMUMSIZE 79 +#define IDS_WARNINITIALRANGE 80 +#define IDS_WARNMAXIMUMRANGE 81 /* propsheet - general */ #define IDD_PROPPAGEGENERAL 100 diff --git a/dll/cpl/sysdm/virtmem.c b/dll/cpl/sysdm/virtmem.c index 6dcd9ad6457..c09b6e40dcf 100644 --- a/dll/cpl/sysdm/virtmem.c +++ b/dll/cpl/sysdm/virtmem.c @@ -110,7 +110,7 @@ ParseMemSettings(PVIRTMEM pVirtMem) TCHAR szVolume[MAX_PATH]; TCHAR *szDisplayString; INT InitialSize = 0; - INT MaxSize = 0; + INT MaximumSize = 0; INT DriveLen; INT PgCnt = 0; @@ -141,17 +141,17 @@ ParseMemSettings(PVIRTMEM pVirtMem) /* FIXME: we only check the first available pagefile in the reg */ GetPageFileSizes(pVirtMem->szPagingFiles, &InitialSize, - &MaxSize); + &MaximumSize); - pVirtMem->Pagefile[PgCnt].InitialValue = InitialSize; - pVirtMem->Pagefile[PgCnt].MaxValue = MaxSize; + pVirtMem->Pagefile[PgCnt].InitialSize = InitialSize; + pVirtMem->Pagefile[PgCnt].MaximumSize = MaximumSize; pVirtMem->Pagefile[PgCnt].bUsed = TRUE; lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); } else { - pVirtMem->Pagefile[PgCnt].InitialValue = 0; - pVirtMem->Pagefile[PgCnt].MaxValue = 0; + pVirtMem->Pagefile[PgCnt].InitialSize = 0; + pVirtMem->Pagefile[PgCnt].MaximumSize = 0; pVirtMem->Pagefile[PgCnt].bUsed = FALSE; lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); } @@ -177,11 +177,11 @@ ParseMemSettings(PVIRTMEM pVirtMem) } } - if ((InitialSize != 0) || (MaxSize != 0)) + if ((InitialSize != 0) || (MaximumSize != 0)) { TCHAR szSize[64]; - _stprintf(szSize, _T("%i - %i"), InitialSize, MaxSize); + _stprintf(szSize, _T("%i - %i"), InitialSize, MaximumSize); _tcscat(szDisplayString, _T("\t")); _tcscat(szDisplayString, szSize); } @@ -216,11 +216,11 @@ WritePageFileSettings(PVIRTMEM pVirtMem) { _stprintf(szText, _T("%s\\pagefile.sys %i %i"), pVirtMem->Pagefile[i].szDrive, - pVirtMem->Pagefile[i].InitialValue, - pVirtMem->Pagefile[i].MaxValue); + pVirtMem->Pagefile[i].InitialSize, + pVirtMem->Pagefile[i].MaximumSize); /* Add it to our overall registry string */ - lstrcat(szPagingFiles + nPos, szText); + lstrcpy(szPagingFiles + nPos, szText); /* Record the position where the next string will start */ nPos += (INT)lstrlen(szText) + 1; @@ -299,8 +299,11 @@ static VOID OnSet(PVIRTMEM pVirtMem) { INT Index; - UINT Value; + UINT InitialSize; + UINT MaximumSize; BOOL bTranslated; + TCHAR szTitle[64]; + TCHAR szMessage[256]; pVirtMem->bSave = TRUE; @@ -315,46 +318,109 @@ OnSet(PVIRTMEM pVirtMem) if (IsDlgButtonChecked(pVirtMem->hSelf, IDC_CUSTOM) == BST_CHECKED) { - Value = GetDlgItemInt(pVirtMem->hSelf, - IDC_INITIALSIZE, - &bTranslated, - FALSE); + InitialSize = GetDlgItemInt(pVirtMem->hSelf, + IDC_INITIALSIZE, + &bTranslated, + FALSE); if (!bTranslated) { - /* FIXME: Show error message instead of setting the edit - field to the previous value */ - SetDlgItemInt(pVirtMem->hSelf, - IDC_INITIALSIZE, - pVirtMem->Pagefile[Index].InitialValue, - FALSE); - } - else - { - pVirtMem->Pagefile[Index].InitialValue = Value; + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + if (LoadString(hApplet, + IDS_WARNINITIALSIZE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])) == 0) + _tcscpy(szMessage, _T("Enter a numeric value for the initial size of the paging file.")); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; } - Value = GetDlgItemInt(pVirtMem->hSelf, - IDC_MAXSIZE, - &bTranslated, - FALSE); + MaximumSize = GetDlgItemInt(pVirtMem->hSelf, + IDC_MAXSIZE, + &bTranslated, + FALSE); if (!bTranslated) { - /* FIXME: Show error message instead of setting the edit - field to the previous value */ - SetDlgItemInt(pVirtMem->hSelf, - IDC_MAXSIZE, - pVirtMem->Pagefile[Index].MaxValue, - FALSE); + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + if (LoadString(hApplet, + IDS_WARNMAXIMUMSIZE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])) == 0) + _tcscpy(szMessage, _T("Enter a numeric value for the maximum size of the paging file.")); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; } - else + + /* Check the valid range of the inial size */ + if (InitialSize < 2 || + InitialSize > pVirtMem->Pagefile[Index].FreeSize) { - pVirtMem->Pagefile[Index].MaxValue = Value; + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + LoadString(hApplet, + IDS_WARNINITIALRANGE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; } + + /* Check the valid range of the maximum size */ + if (MaximumSize < InitialSize || + MaximumSize > pVirtMem->Pagefile[Index].FreeSize) + { + if (LoadString(hApplet, + IDS_MESSAGEBOXTITLE, + szTitle, + sizeof(szTitle) / sizeof(szTitle[0])) == 0) + _tcscpy(szTitle, _T("System control panel applet")); + + LoadString(hApplet, + IDS_WARNMAXIMUMRANGE, + szMessage, + sizeof(szMessage) / sizeof(szMessage[0])); + + MessageBox(NULL, + szMessage, + szTitle, + MB_ICONWARNING | MB_OK); + return; + } + + pVirtMem->Pagefile[Index].InitialSize = InitialSize; + pVirtMem->Pagefile[Index].MaximumSize = MaximumSize; + pVirtMem->Pagefile[Index].bUsed = TRUE; } else { /* set sizes to 0 */ - pVirtMem->Pagefile[Index].InitialValue = pVirtMem->Pagefile[Index].MaxValue = 0; + pVirtMem->Pagefile[Index].InitialSize = 0; + pVirtMem->Pagefile[Index].MaximumSize = 0; // check to see if this drive is used for a paging file if (IsDlgButtonChecked(pVirtMem->hSelf, @@ -397,12 +463,13 @@ OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) if (GetDiskFreeSpaceEx(pVirtMem->Pagefile[Index].szDrive, NULL, NULL, &FreeBytes)) { + pVirtMem->Pagefile[Index].FreeSize = FreeBytes.QuadPart >> 20; _stprintf(szBuffer, _T("%I64u MB"), FreeBytes.QuadPart / (1024 * 1024)); SetDlgItemText(hwndDlg, IDC_SPACEAVAIL, szBuffer); } - if (pVirtMem->Pagefile[Index].InitialValue != 0 && - pVirtMem->Pagefile[Index].MaxValue != 0) + if (pVirtMem->Pagefile[Index].InitialSize != 0 && + pVirtMem->Pagefile[Index].MaximumSize != 0) { /* enable and fill the custom values */ EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); @@ -410,12 +477,12 @@ OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) SetDlgItemInt(pVirtMem->hSelf, IDC_INITIALSIZE, - pVirtMem->Pagefile[Index].InitialValue, + pVirtMem->Pagefile[Index].InitialSize, FALSE); SetDlgItemInt(pVirtMem->hSelf, IDC_MAXSIZE, - pVirtMem->Pagefile[Index].MaxValue, + pVirtMem->Pagefile[Index].MaximumSize, FALSE); CheckDlgButton(pVirtMem->hSelf, @@ -459,7 +526,7 @@ OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) FileSize = 0; for (i = 0; i < 26; i++) { - FileSize += pVirtMem->Pagefile[i].InitialValue; + FileSize += pVirtMem->Pagefile[i].InitialSize; } _stprintf(szBuffer, _T("%u MB"), FileSize); SetDlgItemText(hwndDlg, IDC_CURRENT, szBuffer); diff --git a/dll/cpl/usrmgr/lang/es-ES.rc b/dll/cpl/usrmgr/lang/es-ES.rc new file mode 100644 index 00000000000..e2afc79cbb8 --- /dev/null +++ b/dll/cpl/usrmgr/lang/es-ES.rc @@ -0,0 +1,219 @@ +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + + +/* Dialogs */ + +IDD_USERS DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Usuarios" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_USERS_LIST, "SysListView32", LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 7, 238, 85, WS_EX_CLIENTEDGE +END + + +IDD_GROUPS DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Grupos" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_GROUPS_LIST, "SysListView32", LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 7, 238, 85, WS_EX_CLIENTEDGE +END + + +IDD_EXTRA DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Extra" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "This space is intentionally left blank", IDC_STATIC, 66, 90, 112, 8 +END + + +IDD_USER_GENERAL DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "General" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "", IDC_USER_GENERAL_NAME, 7, 12, 112, 8 + LTEXT "Nombre completo:", -1, 7, 46, 63, 8 + EDITTEXT IDC_USER_GENERAL_FULL_NAME,77,43,168,13,ES_AUTOHSCROLL + LTEXT "Descripción:", -1, 7, 64, 63, 8 + EDITTEXT IDC_USER_GENERAL_DESCRIPTION,77,61,168,13,ES_AUTOHSCROLL + AUTOCHECKBOX "El usuario debe cambiar la contraseńa en el siguiente inicio de sesión",IDC_USER_GENERAL_FORCE_CHANGE,7,82,210,10 + AUTOCHECKBOX "El usuario no puede cambiar la contraseńa",IDC_USER_GENERAL_CANNOT_CHANGE,7,95,210,10 + AUTOCHECKBOX "La contraseńa nunca caduca",IDC_USER_GENERAL_NEVER_EXPIRES,7,108,210,10 + AUTOCHECKBOX "Cuenta deshabilitada",IDC_USER_GENERAL_DISABLED,7,121,210,10 + AUTOCHECKBOX "La cuenta está bloqueada",IDC_USER_GENERAL_LOCKED,7,134,210,10 +END + + +IDD_USER_MEMBERSHIP DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Miembro de" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Miembro de:", -1, 7, 7, 56, 8 + CONTROL "", IDC_USER_MEMBERSHIP_LIST, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 18, 238, 173, WS_EX_CLIENTEDGE + PUSHBUTTON "Agregar...", IDC_USER_MEMBERSHIP_ADD, 7, 197, 50, 14 + PUSHBUTTON "Quitar", IDC_USER_MEMBERSHIP_REMOVE, 61, 197, 50, 14, WS_DISABLED +END + + +IDD_USER_PROFILE DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Perfil" +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Perfil de usuario ", -1, 7, 7, 238, 54 + LTEXT "Ruta de acceso al perfil:", -1, 16, 22, 55, 8 + EDITTEXT IDC_USER_PROFILE_PATH, 78, 19, 160, 13, ES_AUTOHSCROLL + LTEXT "Archivo de comandos de inicio de sesión:", -1, 16, 40, 55, 8 + EDITTEXT IDC_USER_PROFILE_SCRIPT, 78, 37, 160, 13, ES_AUTOHSCROLL + + GROUPBOX "Carpeta particular ", -1, 7, 68, 238, 54 + AUTORADIOBUTTON "Ruta de acceso local:", IDC_USER_PROFILE_LOCAL, 16, 83, 60, 10 + AUTORADIOBUTTON "Conectar:", IDC_USER_PROFILE_REMOTE, 16, 100, 60, 10 + EDITTEXT IDC_USER_PROFILE_LOCAL_PATH, 78, 81, 160, 13, ES_AUTOHSCROLL + COMBOBOX IDC_USER_PROFILE_DRIVE, 78, 99, 26, 160, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL + LTEXT "A:", -1, 112, 101, 12, 8 + EDITTEXT IDC_USER_PROFILE_REMOTE_PATH, 130, 99, 108, 13, ES_AUTOHSCROLL +END + + +IDD_GROUP_GENERAL DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "General" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "", IDC_GROUP_GENERAL_NAME, 7, 12, 112, 8 + LTEXT "Descripción:", -1, 7, 45, 46, 8 + EDITTEXT IDC_GROUP_GENERAL_DESCRIPTION,65,42,180,13,ES_AUTOHSCROLL + LTEXT "Miembros:", -1, 7, 63, 45, 8 + CONTROL "", IDC_GROUP_GENERAL_MEMBERS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 74, 238, 117, WS_EX_CLIENTEDGE + PUSHBUTTON "Ańadir...", IDC_GROUP_GENERAL_ADD, 7, 197, 50, 14 + PUSHBUTTON "Quitar", IDC_GROUP_GENERAL_REMOVE, 61, 197, 50, 14, WS_DISABLED +END + + +IDD_CHANGE_PASSWORD DIALOGEX DISCARDABLE 0, 0, 267, 74 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Cambiar contraseńa" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_EDIT_PASSWORD1,107,7,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Nueva contraseńa:", -1,7,10,96,8 + EDITTEXT IDC_EDIT_PASSWORD2,107,25,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Confirmar la contraseńa:", -1,7,28,96,8 + DEFPUSHBUTTON "Aceptar",IDOK,156,53,50,14 + PUSHBUTTON "Cancelar",IDCANCEL,210,53,50,14 +END + + +IDD_USER_NEW DIALOGEX DISCARDABLE 0, 0, 267, 200 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Nuevo usuario" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_USER_NEW_NAME,107,7,153,14,ES_AUTOHSCROLL + RTEXT "Nombre de usuario:", -1,7,10,96,8 + EDITTEXT IDC_USER_NEW_FULL_NAME,107,25,153,14,ES_AUTOHSCROLL + RTEXT "Nombre completo:", -1,7,28,96,8 + EDITTEXT IDC_USER_NEW_DESCRIPTION,107,43,153,14,ES_AUTOHSCROLL + RTEXT "Descripción:", -1,7,46,96,8 + EDITTEXT IDC_USER_NEW_PASSWORD1,107,67,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Contraseńa:", -1,7,70,96,8 + EDITTEXT IDC_USER_NEW_PASSWORD2,107,85,153,14,ES_AUTOHSCROLL | ES_PASSWORD + RTEXT "Confirmar la contraseńa:", -1,7,88,96,8 + AUTOCHECKBOX "El usuario debe cambiar la contraseńa en el siguiente inicio de sesión",IDC_USER_NEW_FORCE_CHANGE,7,109,200,10 + AUTOCHECKBOX "El usuario no puede cambiar la contraseńa",IDC_USER_NEW_CANNOT_CHANGE,7,123,200,10,WS_DISABLED + AUTOCHECKBOX "La contraseńa nunca caduca",IDC_USER_NEW_NEVER_EXPIRES,7,137,200,10,WS_DISABLED + AUTOCHECKBOX "Cuenta deshabilitada",IDC_USER_NEW_DISABLED,7,151,200,10 + DEFPUSHBUTTON "Aceptar",IDOK,156,179,50,14,WS_DISABLED + PUSHBUTTON "Cancelar",IDCANCEL,210,179,50,14 +END + + +IDD_GROUP_NEW DIALOGEX DISCARDABLE 0, 0, 267, 74 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Nuevo grupo" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_GROUP_NEW_NAME,107,7,153,14,ES_AUTOHSCROLL + RTEXT "Nombre del grupo:", -1,7,10,96,8 + EDITTEXT IDC_GROUP_NEW_DESCRIPTION,107,25,153,14,ES_AUTOHSCROLL + RTEXT "Descripción:", -1,7,28,96,8 + DEFPUSHBUTTON "Aceptar",IDOK,156,53,50,14,WS_DISABLED + PUSHBUTTON "Cancelar",IDCANCEL,210,53,50,14 +END + + +IDD_USER_ADD_MEMBERSHIP DIALOGEX DISCARDABLE 0, 0, 252, 223 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT +CAPTION "Pertenencia a grupos" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Miembro de:", -1, 7, 7, 56, 8 + CONTROL "", IDC_USER_ADD_MEMBERSHIP_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + 7, 18, 238, 173, WS_EX_CLIENTEDGE + DEFPUSHBUTTON "Aceptar",IDOK,141,197,50,14 + PUSHBUTTON "Cancelar",IDCANCEL,195,197,50,14 +END + + +/* Menus */ + +IDM_POPUP_GROUP MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "Nuevo grupo...", IDM_GROUP_NEW + END + POPUP "" + BEGIN + MENUITEM "Ańadir miembro", IDM_GROUP_ADD_MEMBER, GRAYED + MENUITEM SEPARATOR + MENUITEM "Borrar", IDM_GROUP_DELETE + MENUITEM "Renombrar", IDM_GROUP_RENAME + MENUITEM SEPARATOR + MENUITEM "Propiedades", IDM_GROUP_PROPERTIES + END +END + + +IDM_POPUP_USER MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "Nuevo usuario...", IDM_USER_NEW + END + POPUP "" + BEGIN + MENUITEM "Cambiar contraseńa", IDM_USER_CHANGE_PASSWORD + MENUITEM SEPARATOR + MENUITEM "Borrar", IDM_USER_DELETE + MENUITEM "Renombrar", IDM_USER_RENAME + MENUITEM SEPARATOR + MENUITEM "Propiedades", IDM_USER_PROPERTIES + END +END + + +/* Strings */ + +STRINGTABLE +BEGIN + IDS_CPLNAME "Cuentas de usuario" + IDS_CPLDESCRIPTION "Gestiona Usuarios y Grupos." +END + +STRINGTABLE +BEGIN + IDS_NAME "Nombre" + IDS_FULLNAME "Nombre completo" + IDS_DESCRIPTION "Descripción" +END diff --git a/dll/cpl/usrmgr/rsrc.rc b/dll/cpl/usrmgr/rsrc.rc index 5e400c134c0..3c5ab7370fe 100644 --- a/dll/cpl/usrmgr/rsrc.rc +++ b/dll/cpl/usrmgr/rsrc.rc @@ -3,5 +3,6 @@ #include "lang/de-DE.rc" #include "lang/en-US.rc" +#include "lang/es-ES.rc" #include "lang/pl-PL.rc" #include "lang/ru-RU.rc" diff --git a/dll/directx/qedit/mediadet.c b/dll/directx/qedit/mediadet.c index 3a13f717bf6..9aeb9c017cc 100644 --- a/dll/directx/qedit/mediadet.c +++ b/dll/directx/qedit/mediadet.c @@ -38,8 +38,8 @@ typedef struct MediaDetImpl { IGraphBuilder *graph; IBaseFilter *source; IBaseFilter *splitter; - long num_streams; - long cur_stream; + LONG num_streams; + LONG cur_stream; IPin *cur_pin; } MediaDetImpl; @@ -168,7 +168,7 @@ static HRESULT WINAPI MediaDet_get_CurrentStream(IMediaDet* iface, LONG *pVal) return S_OK; } -static HRESULT SetCurPin(MediaDetImpl *This, long strm) +static HRESULT SetCurPin(MediaDetImpl *This, LONG strm) { IEnumPins *pins; IPin *pin; diff --git a/dll/directx/qedit/qedit.rbuild b/dll/directx/qedit/qedit.rbuild index f3285f4ef48..0fd54bf8ea3 100644 --- a/dll/directx/qedit/qedit.rbuild +++ b/dll/directx/qedit/qedit.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/dll/directx/qedit/regsvr.c b/dll/directx/qedit/regsvr.c index d70c8222ee8..d007311840a 100644 --- a/dll/directx/qedit/regsvr.c +++ b/dll/directx/qedit/regsvr.c @@ -326,5 +326,5 @@ HRESULT WINAPI DllUnregisterServer(void) TRACE("\n"); hr = unregister_coclasses(coclass_list); - return S_OK; + return hr; } diff --git a/dll/directx/qedit/samplegrabber.c b/dll/directx/qedit/samplegrabber.c index 78a7306e10e..78979fecf28 100644 --- a/dll/directx/qedit/samplegrabber.c +++ b/dll/directx/qedit/samplegrabber.c @@ -489,7 +489,7 @@ static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) REFERENCE_TIME tStart, tEnd; if (This->bufferLen >= 0) { BYTE *data = 0; - long size = IMediaSample_GetActualDataLength(sample); + LONG size = IMediaSample_GetActualDataLength(sample); if (size >= 0 && SUCCEEDED(IMediaSample_GetPointer(sample, &data))) { if (!data) size = 0; @@ -527,7 +527,7 @@ static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) case 1: { BYTE *data = 0; - long size = IMediaSample_GetActualDataLength(sample); + LONG size = IMediaSample_GetActualDataLength(sample); if (size && SUCCEEDED(IMediaSample_GetPointer(sample, &data)) && data) ISampleGrabberCB_BufferCB(This->grabberIface, time, data, size); } @@ -535,7 +535,7 @@ static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) case -1: break; default: - FIXME("unsupported method %ld\n", (long int)This->grabberMethod); + FIXME("unsupported method %d\n", This->grabberMethod); /* do not bother us again */ This->grabberMethod = -1; } diff --git a/dll/directx/quartz/acmwrapper.c b/dll/directx/quartz/acmwrapper.c index c275d833979..a0323911707 100644 --- a/dll/directx/quartz/acmwrapper.c +++ b/dll/directx/quartz/acmwrapper.c @@ -105,7 +105,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample tMed = tStart; - TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream); + TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) diff --git a/dll/directx/quartz/avidec.c b/dll/directx/quartz/avidec.c index 8469bbc9f29..b7d45e93890 100644 --- a/dll/directx/quartz/avidec.c +++ b/dll/directx/quartz/avidec.c @@ -101,7 +101,7 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) cbSrcStream = IMediaSample_GetActualDataLength(pSample); - TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream); + TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) { diff --git a/dll/directx/quartz/avisplit.c b/dll/directx/quartz/avisplit.c index 42ec2ae2b34..61078805903 100644 --- a/dll/directx/quartz/avisplit.c +++ b/dll/directx/quartz/avisplit.c @@ -178,7 +178,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe { AVISTDINDEX *index = stream->stdindex[stream->index]; AVISTDINDEX_ENTRY *entry = &index->aIndex[stream->pos]; - BOOL keyframe; /* End of file */ if (stream->index >= stream->entries) @@ -189,7 +188,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe } rtSampleStart = index->qwBaseOffset; - keyframe = !(entry->dwSize >> 31); rtSampleStart += entry->dwOffset; rtSampleStart = MEDIATIME_FROM_BYTES(rtSampleStart); @@ -208,7 +206,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe { DWORD flags = This->oldindex->aIndex[stream->pos].dwFlags; DWORD size = This->oldindex->aIndex[stream->pos].dwSize; - BOOL keyframe; /* End of file */ if (stream->index) @@ -218,8 +215,6 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe return S_FALSE; } - keyframe = !!(flags & AVIIF_KEYFRAME); - rtSampleStart = MEDIATIME_FROM_BYTES(This->offset); rtSampleStart += MEDIATIME_FROM_BYTES(This->oldindex->aIndex[stream->pos].dwOffset); rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(size); @@ -775,7 +770,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE { const AVISUPERINDEX *pIndex = (const AVISUPERINDEX *)pChunk; DWORD x; - long rest = pIndex->cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex[0]) * ANYSIZE_ARRAY; + UINT rest = pIndex->cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex[0]) * ANYSIZE_ARRAY; if (pIndex->cb < sizeof(AVISUPERINDEX) - sizeof(RIFFCHUNK)) { diff --git a/dll/directx/quartz/dsoundrender.c b/dll/directx/quartz/dsoundrender.c index 1d87a7f0047..b327c00da9b 100644 --- a/dll/directx/quartz/dsoundrender.c +++ b/dll/directx/quartz/dsoundrender.c @@ -78,8 +78,8 @@ typedef struct DSoundRenderImpl HANDLE state_change, blocked; - long volume; - long pan; + LONG volume; + LONG pan; } DSoundRenderImpl; /* Seeking is not needed for a renderer, rely on newsegment for the appropriate changes */ @@ -238,7 +238,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) { DSoundRenderImpl *This = iface; LPBYTE pbSrcStream = NULL; - long cbSrcStream = 0; + LONG cbSrcStream = 0; REFERENCE_TIME tStart, tStop; HRESULT hr; AM_MEDIA_TYPE *amt; @@ -344,7 +344,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) } cbSrcStream = IMediaSample_GetActualDataLength(pSample); - TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream); + TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); #if 0 /* For debugging purpose */ { @@ -677,7 +677,7 @@ static HRESULT WINAPI DSoundRender_GetState(IBaseFilter * iface, DWORD dwMilliSe } LeaveCriticalSection(&This->csFilter); - return S_OK; + return hr; } static HRESULT WINAPI DSoundRender_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) @@ -877,11 +877,11 @@ static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin { hr = IDirectSoundBuffer_SetVolume(DSImpl->dsbuffer, DSImpl->volume); if (FAILED(hr)) - ERR("Can't set volume to %ld (%x)\n", DSImpl->volume, hr); + ERR("Can't set volume to %d (%x)\n", DSImpl->volume, hr); hr = IDirectSoundBuffer_SetPan(DSImpl->dsbuffer, DSImpl->pan); if (FAILED(hr)) - ERR("Can't set pan to %ld (%x)\n", DSImpl->pan, hr); + ERR("Can't set pan to %d (%x)\n", DSImpl->pan, hr); DSImpl->write_pos = 0; hr = S_OK; diff --git a/dll/directx/quartz/enumfilters.c b/dll/directx/quartz/enumfilters.c index ca6a98941bc..ab1f6ec6a72 100644 --- a/dll/directx/quartz/enumfilters.c +++ b/dll/directx/quartz/enumfilters.c @@ -126,6 +126,9 @@ static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched); + if (!ppFilters) + return E_POINTER; + for (i = 0; i < cFetched; i++) { ppFilters[i] = This->ppFilters[This->uIndex + i]; diff --git a/dll/directx/quartz/filtergraph.c b/dll/directx/quartz/filtergraph.c index 3e9a1da1b82..18bf97c392b 100644 --- a/dll/directx/quartz/filtergraph.c +++ b/dll/directx/quartz/filtergraph.c @@ -45,14 +45,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct { - HWND hWnd; /* Target window */ - long msg; /* User window message */ - long instance; /* User data */ - int disabled; /* Disabled messages posting */ + HWND hWnd; /* Target window */ + UINT msg; /* User window message */ + LONG_PTR instance; /* User data */ + int disabled; /* Disabled messages posting */ } WndNotify; typedef struct { - long lEventCode; /* Event code */ + LONG lEventCode; /* Event code */ LONG_PTR lParam1; /* Param1 */ LONG_PTR lParam2; /* Param2 */ } Event; @@ -120,7 +120,7 @@ static int EventsQueue_PutEvent(EventsQueue* omr, const Event* evt) return TRUE; } -static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, long msTimeOut) +static int EventsQueue_GetEvent(EventsQueue* omr, Event* evt, LONG msTimeOut) { if (WaitForSingleObject(omr->msg_event, msTimeOut) != WAIT_OBJECT_0) return FALSE; @@ -182,7 +182,7 @@ typedef struct _IFilterGraphImpl { LPWSTR * pFilterNames; int nFilters; int filterCapacity; - long nameIndex; + LONG nameIndex; IReferenceClock *refClock; EventsQueue evqueue; HANDLE hEventCompletion; @@ -4970,7 +4970,7 @@ static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface, This->notif.hWnd = (HWND)hwnd; This->notif.msg = lMsg; - This->notif.instance = (long) lInstanceData; + This->notif.instance = lInstanceData; return S_OK; } @@ -5055,30 +5055,26 @@ static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClass static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) { - FIXME("(): stub\n"); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_Stop((IMediaControl*)&This->IMediaControl_vtbl); } static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) { - FIXME("(): stub\n"); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_Pause((IMediaControl*)&This->IMediaControl_vtbl); } static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart) { - FIXME("(0x%s): stub\n", wine_dbgstr_longlong(tStart)); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_Run((IMediaControl*)&This->IMediaControl_vtbl); } static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState) { - FIXME("(%d, %p): stub\n", dwMsTimeout, pState); - - return E_NOTIMPL; + ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return MediaControl_GetState((IMediaControl*)&This->IMediaControl_vtbl, dwMsTimeout, (OAFilterState*)pState); } static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock) diff --git a/dll/directx/quartz/filtermapper.c b/dll/directx/quartz/filtermapper.c index bacb72950d6..aeacfac386e 100644 --- a/dll/directx/quartz/filtermapper.c +++ b/dll/directx/quartz/filtermapper.c @@ -1778,7 +1778,7 @@ static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData* iface, prf2 = CoTaskMemAlloc(sizeof(*prf2)); if (!prf2) return E_OUTOFMEMORY; - *ppRegFilter2 = (BYTE *)&prf2; + *ppRegFilter2 = (BYTE *)prf2; hr = FM2_ReadFilterData(pData, prf2); if (FAILED(hr)) diff --git a/dll/directx/quartz/memallocator.c b/dll/directx/quartz/memallocator.c index 7f799c93b7d..a1c4473238f 100644 --- a/dll/directx/quartz/memallocator.c +++ b/dll/directx/quartz/memallocator.c @@ -534,7 +534,7 @@ static HRESULT WINAPI StdMediaSample2_GetTime(IMediaSample2 * iface, REFERENCE_T hr = S_OK; } - return S_OK; + return hr; } static HRESULT WINAPI StdMediaSample2_SetTime(IMediaSample2 * iface, REFERENCE_TIME * pStart, REFERENCE_TIME * pEnd) @@ -785,7 +785,7 @@ static HRESULT StdMemAllocator_Alloc(IMemAllocator * iface) StdMemAllocator *This = (StdMemAllocator *)iface; StdMediaSample2 * pSample = NULL; SYSTEM_INFO si; - long i; + LONG i; assert(list_empty(&This->base.free_list)); diff --git a/dll/directx/quartz/mpegsplit.c b/dll/directx/quartz/mpegsplit.c index e44a10fcca1..7eb2d2c213f 100644 --- a/dll/directx/quartz/mpegsplit.c +++ b/dll/directx/quartz/mpegsplit.c @@ -246,11 +246,8 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample, BYTE *pbSrcStream; DWORD cbSrcStream = 0; REFERENCE_TIME tStart, tStop, tAviStart = This->position; - Parser_OutputPin * pOutputPin; HRESULT hr; - pOutputPin = (Parser_OutputPin*)This->Parser.ppPins[1]; - hr = IMediaSample_GetTime(pSample, &tStart, &tStop); if (SUCCEEDED(hr)) { diff --git a/dll/directx/quartz/pin.c b/dll/directx/quartz/pin.c index ca34d9331c5..fd0d5a2e522 100644 --- a/dll/directx/quartz/pin.c +++ b/dll/directx/quartz/pin.c @@ -1834,7 +1834,7 @@ HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinI return E_FAIL; } -HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) +HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) { OutputPin * pPinImpl; diff --git a/dll/directx/quartz/pin.h b/dll/directx/quartz/pin.h index 2cbaddba0f9..e356ef32f53 100644 --- a/dll/directx/quartz/pin.h +++ b/dll/directx/quartz/pin.h @@ -143,7 +143,7 @@ typedef struct PullPin /*** Constructors ***/ HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *, IPin ** ppPin); -HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); +HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, STOPPROCESSPROC, REQUESTPROC pCustomRequest, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); /**************************/ diff --git a/dll/directx/quartz/quartz.rbuild b/dll/directx/quartz/quartz.rbuild index b7097f6ff1f..4a86c54b112 100644 --- a/dll/directx/quartz/quartz.rbuild +++ b/dll/directx/quartz/quartz.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/dll/directx/quartz/videorenderer.c b/dll/directx/quartz/videorenderer.c index b31959eed21..268373f1888 100644 --- a/dll/directx/quartz/videorenderer.c +++ b/dll/directx/quartz/videorenderer.c @@ -82,8 +82,8 @@ typedef struct VideoRendererImpl RECT SourceRect; RECT DestRect; RECT WindowPos; - long VideoWidth; - long VideoHeight; + LONG VideoWidth; + LONG VideoHeight; IUnknown * pUnkOuter; BOOL bUnkOuterValid; BOOL bAggregatable; @@ -287,7 +287,6 @@ static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, return VFW_E_RUNTIME_ERROR; } - TRACE("biSize = %d\n", bmiHeader->biSize); TRACE("biWidth = %d\n", bmiHeader->biWidth); TRACE("biHeight = %d\n", bmiHeader->biHeight); @@ -344,7 +343,7 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) { VideoRendererImpl *This = iface; LPBYTE pbSrcStream = NULL; - long cbSrcStream = 0; + LONG cbSrcStream = 0; REFERENCE_TIME tStart, tStop; HRESULT hr; @@ -396,7 +395,7 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) cbSrcStream = IMediaSample_GetActualDataLength(pSample); - TRACE("val %p %ld\n", pbSrcStream, cbSrcStream); + TRACE("val %p %d\n", pbSrcStream, cbSrcStream); #if 0 /* For debugging purpose */ { @@ -483,6 +482,7 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)) { VideoRendererImpl* This = iface; + LONG height; if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { @@ -490,7 +490,11 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt This->SourceRect.left = 0; This->SourceRect.top = 0; This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth; - This->SourceRect.bottom = This->VideoHeight = format->bmiHeader.biHeight; + height = format->bmiHeader.biHeight; + if (height < 0) + This->SourceRect.bottom = This->VideoHeight = -height; + else + This->SourceRect.bottom = This->VideoHeight = height; } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { @@ -499,7 +503,11 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt This->SourceRect.left = 0; This->SourceRect.top = 0; This->SourceRect.right = This->VideoWidth = format2->bmiHeader.biWidth; - This->SourceRect.bottom = This->VideoHeight = format2->bmiHeader.biHeight; + height = format2->bmiHeader.biHeight; + if (height < 0) + This->SourceRect.bottom = This->VideoHeight = -height; + else + This->SourceRect.bottom = This->VideoHeight = height; } else { @@ -1176,10 +1184,25 @@ static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface, /*** IBasicVideo methods ***/ static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame) { + AM_MEDIA_TYPE *pmt; ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pAvgTimePerFrame); + if (!This->pInputPin->pin.pConnectedTo) + return VFW_E_NOT_CONNECTED; + TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); + + pmt = &This->pInputPin->pin.mtCurrent; + if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { + VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)pmt->pbFormat; + *pAvgTimePerFrame = vih->AvgTimePerFrame; + } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { + VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)pmt->pbFormat; + *pAvgTimePerFrame = vih->AvgTimePerFrame; + } else { + ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); + *pAvgTimePerFrame = 0; + } return S_OK; } @@ -1779,9 +1802,6 @@ static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface, TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx); - if (WindowStyleEx & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) - return E_INVALIDARG; - if (!SetWindowLongA(This->hWnd, GWL_EXSTYLE, WindowStyleEx)) return E_FAIL; @@ -1805,7 +1825,7 @@ static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface, TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow); - This->AutoShow = 1; /* FIXME: Should be AutoShow */; + This->AutoShow = AutoShow; return S_OK; } @@ -1825,16 +1845,20 @@ static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface, LONG WindowState) { ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, WindowState); - + TRACE("(%p/%p)->(%d)\n", This, iface, WindowState); + ShowWindow(This->hWnd, WindowState); return S_OK; } static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface, LONG *WindowState) { + WINDOWPLACEMENT place; ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, WindowState); + place.length = sizeof(place); + GetWindowPlacement(This->hWnd, &place); + TRACE("(%p/%p)->(%p)\n", This, iface, WindowState); + *WindowState = place.showCmd; return S_OK; } diff --git a/dll/directx/wine/d3d8/device.c b/dll/directx/wine/d3d8/device.c index 11697b2ff26..12ed0fbfd38 100644 --- a/dll/directx/wine/d3d8/device.c +++ b/dll/directx/wine/d3d8/device.c @@ -171,18 +171,19 @@ static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enu if (t->free_entries) { + DWORD index = t->free_entries - t->entries; /* Use a free handle */ entry = t->free_entries; if (entry->type != D3D8_HANDLE_FREE) { - ERR("Handle %u(%p) is in the free list, but has type %#x.\n", (entry - t->entries), entry, entry->type); + ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type); return D3D8_INVALID_HANDLE; } t->free_entries = entry->object; entry->object = object; entry->type = type; - return entry - t->entries; + return index; } if (!(t->entry_count < t->table_size)) @@ -324,6 +325,7 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { HeapFree(GetProcessHeap(), 0, This->decls); IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice); IWineD3DDevice_Release(This->WineD3DDevice); HeapFree(GetProcessHeap(), 0, This->handle_table.entries); HeapFree(GetProcessHeap(), 0, This); @@ -2762,6 +2764,19 @@ static const IWineD3DDeviceParentVtbl d3d8_wined3d_device_parent_vtbl = device_parent_CreateSwapChain, }; +static void setup_fpu(void) +{ + WORD cw; + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ volatile ("fnstcw %0" : "=m" (cw)); + cw = (cw & ~0xf3f) | 0x3f; + __asm__ volatile ("fldcw %0" : : "m" (cw)); +#else + FIXME("FPU setup not implemented for this platform.\n"); +#endif +} + HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) { @@ -2780,6 +2795,8 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte } device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE; + if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); + wined3d_mutex_lock(); hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device, (IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice); @@ -2791,6 +2808,19 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte return hr; } + if (!parameters->Windowed) + { + if (!focus_window) focus_window = parameters->hDeviceWindow; + if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window))) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + IWineD3DDevice_Release(device->WineD3DDevice); + wined3d_mutex_unlock(); + HeapFree(GetProcessHeap(), 0, device->handle_table.entries); + return hr; + } + } + if (flags & D3DCREATE_MULTITHREADED) IWineD3DDevice_SetMultithreaded(device->WineD3DDevice); wined3d_parameters.BackBufferWidth = parameters->BackBufferWidth; @@ -2813,6 +2843,7 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte if (FAILED(hr)) { WARN("Failed to initialize 3D, hr %#x.\n", hr); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, device->handle_table.entries); @@ -2855,6 +2886,7 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte err: wined3d_mutex_lock(); IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D8CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, device->handle_table.entries); diff --git a/dll/directx/wine/d3d9/device.c b/dll/directx/wine/d3d9/device.c index 79a9ba01834..b9f539e0b28 100644 --- a/dll/directx/wine/d3d9/device.c +++ b/dll/directx/wine/d3d9/device.c @@ -271,6 +271,7 @@ static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(LPDIRECT3DDEV HeapFree(GetProcessHeap(), 0, This->convertedDecls); IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice); IWineD3DDevice_Release(This->WineD3DDevice); wined3d_mutex_unlock(); @@ -2821,6 +2822,19 @@ static const IWineD3DDeviceParentVtbl d3d9_wined3d_device_parent_vtbl = device_parent_CreateSwapChain, }; +static void setup_fpu(void) +{ + WORD cw; + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ volatile ("fnstcw %0" : "=m" (cw)); + cw = (cw & ~0xf3f) | 0x3f; + __asm__ volatile ("fldcw %0" : : "m" (cw)); +#else + FIXME("FPU setup not implemented for this platform.\n"); +#endif +} + HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) { @@ -2832,6 +2846,8 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte device->device_parent_vtbl = &d3d9_wined3d_device_parent_vtbl; device->ref = 1; + if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu(); + wined3d_mutex_lock(); hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device, (IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice); @@ -2842,6 +2858,18 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte return hr; } + if (!parameters->Windowed) + { + if (!focus_window) focus_window = parameters->hDeviceWindow; + if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window))) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + IWineD3DDevice_Release(device->WineD3DDevice); + wined3d_mutex_unlock(); + return hr; + } + } + if (flags & D3DCREATE_ADAPTERGROUP_DEVICE) { WINED3DCAPS caps; @@ -2885,6 +2913,7 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte if (FAILED(hr)) { WARN("Failed to initialize 3D, hr %#x.\n", hr); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); HeapFree(GetProcessHeap(), 0, wined3d_parameters); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); @@ -2921,6 +2950,7 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte ERR("Failed to allocate FVF vertex declaration map memory.\n"); wined3d_mutex_lock(); IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D9CB_DestroySwapChain); + IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice); IWineD3DDevice_Release(device->WineD3DDevice); wined3d_mutex_unlock(); return E_OUTOFMEMORY; diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c index 122c31b8cb8..a7522f91789 100644 --- a/dll/directx/wine/ddraw/ddraw.c +++ b/dll/directx/wine/ddraw/ddraw.c @@ -264,8 +264,8 @@ IDirectDrawImpl_AddRef(IDirectDraw7 *iface) void IDirectDrawImpl_Destroy(IDirectDrawImpl *This) { - /* Clear the cooplevel to restore window and display mode */ IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)This, NULL, DDSCL_NORMAL); + IDirectDraw7_RestoreDisplayMode((IDirectDraw7 *)This); /* Destroy the device window if we created one */ if(This->devicewindow != 0) @@ -441,12 +441,11 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface, /* Switching from fullscreen? */ if(This->cooperative_level & DDSCL_FULLSCREEN) { - /* Restore the display mode */ - IDirectDraw7_RestoreDisplayMode(iface); - This->cooperative_level &= ~DDSCL_FULLSCREEN; This->cooperative_level &= ~DDSCL_EXCLUSIVE; This->cooperative_level &= ~DDSCL_ALLOWMODEX; + + IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice); } /* Don't override focus windows or private device windows */ @@ -483,6 +482,13 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface, !(This->devicewindow) && (hwnd != window) ) { + HRESULT hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd); + if (FAILED(hr)) + { + ERR("Failed to acquire focus window, hr %#x.\n", hr); + LeaveCriticalSection(&ddraw_cs); + return hr; + } This->dest_window = hwnd; } } @@ -1514,11 +1520,24 @@ IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface, IDirectDrawSurface7 **Surface) { IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface); + IWineD3DSurface *wined3d_surface; + HRESULT hr; - /* Implementation idea if needed: Loop through all surfaces and compare - * their hdc with hdc. Implement it in WineD3D! */ - return DDERR_NOTFOUND; + TRACE("iface %p, dc %p, surface %p.\n", iface, hdc, Surface); + + if (!Surface) return E_INVALIDARG; + + hr = IWineD3DDevice_GetSurfaceFromDC(This->wineD3DDevice, hdc, &wined3d_surface); + if (FAILED(hr)) + { + TRACE("No surface found for dc %p.\n", hdc); + *Surface = NULL; + return DDERR_NOTFOUND; + } + + IWineD3DSurface_GetParent(wined3d_surface, (IUnknown **)Surface); + TRACE("Returning surface %p.\n", Surface); + return DD_OK; } /***************************************************************************** diff --git a/dll/directx/wine/ddraw/ddraw.rbuild b/dll/directx/wine/ddraw/ddraw.rbuild index f8d9c92c279..962cd7a96ad 100644 --- a/dll/directx/wine/ddraw/ddraw.rbuild +++ b/dll/directx/wine/ddraw/ddraw.rbuild @@ -1,6 +1,6 @@ - + . diff --git a/dll/directx/wine/ddraw/ddraw_thunks.c b/dll/directx/wine/ddraw/ddraw_thunks.c index dc71bf55a9c..9d606245272 100644 --- a/dll/directx/wine/ddraw/ddraw_thunks.c +++ b/dll/directx/wine/ddraw/ddraw_thunks.c @@ -290,6 +290,7 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc, set_surf_version(impl, 1); IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw1(This)); impl->ifaceToRelease = NULL; + return hr; } @@ -309,11 +310,13 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc, *ppSurface = NULL; return hr; } + impl = (IDirectDrawSurfaceImpl *)pSurface7; *ppSurface = (IDirectDrawSurface *)&impl->IDirectDrawSurface3_vtbl; set_surf_version(impl, 2); IDirectDraw7_Release((IDirectDraw7 *)ddraw_from_ddraw2(This)); impl->ifaceToRelease = NULL; + return hr; } diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c index 13ecfa133ac..9a4e5c73204 100644 --- a/dll/directx/wine/ddraw/device.c +++ b/dll/directx/wine/ddraw/device.c @@ -2409,22 +2409,60 @@ IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, case D3DRENDERSTATE_TEXTUREMIN: { WINED3DTEXTUREFILTERTYPE tex_min; + WINED3DTEXTUREFILTERTYPE tex_mip; hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, - 0, WINED3DSAMP_MINFILTER, - &tex_min); + 0, WINED3DSAMP_MINFILTER, &tex_min); + if (FAILED(hr)) + { + LeaveCriticalSection(&ddraw_cs); + return hr; + } + hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, + 0, WINED3DSAMP_MIPFILTER, &tex_mip); switch (tex_min) { case WINED3DTEXF_POINT: - *Value = D3DFILTER_NEAREST; + switch (tex_mip) + { + case WINED3DTEXF_NONE: + *Value = D3DFILTER_NEAREST; + break; + case WINED3DTEXF_POINT: + *Value = D3DFILTER_MIPNEAREST; + break; + case WINED3DTEXF_LINEAR: + *Value = D3DFILTER_LINEARMIPNEAREST; + break; + default: + ERR("Unhandled mip filter %#x.\n", tex_mip); + *Value = D3DFILTER_NEAREST; + break; + } break; case WINED3DTEXF_LINEAR: - *Value = D3DFILTER_LINEAR; + switch (tex_mip) + { + case WINED3DTEXF_NONE: + *Value = D3DFILTER_LINEAR; + break; + case WINED3DTEXF_POINT: + *Value = D3DFILTER_MIPLINEAR; + break; + case WINED3DTEXF_LINEAR: + *Value = D3DFILTER_LINEARMIPLINEAR; + break; + default: + ERR("Unhandled mip filter %#x.\n", tex_mip); + *Value = D3DFILTER_LINEAR; + break; + } break; default: - ERR("Unhandled texture mag %d !\n",tex_min); - *Value = 0; + ERR("Unhandled texture min filter %#x.\n",tex_min); + *Value = D3DFILTER_NEAREST; + break; } break; } @@ -2441,8 +2479,20 @@ IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, Value); break; + case D3DRENDERSTATE_BORDERCOLOR: + FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n"); + hr = E_NOTIMPL; + break; + default: - /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */ + if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 + && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31) + { + FIXME("Unhandled stipple pattern render state (%#x).\n", + RenderStateType); + hr = E_NOTIMPL; + break; + } hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice, RenderStateType, Value); @@ -2640,22 +2690,39 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, /* Some render states need special care */ switch(RenderStateType) { + /* + * The ddraw texture filter mapping works like this: + * D3DFILTER_NEAREST Point min/mag, no mip + * D3DFILTER_MIPNEAREST Point min/mag, point mip + * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip + * + * D3DFILTER_LINEAR Linear min/mag, no mip + * D3DFILTER_MIPLINEAR Linear min/mag, point mip + * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip + * + * This is the opposite of the GL naming convention, + * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR. + */ case D3DRENDERSTATE_TEXTUREMAG: { - WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT; + WINED3DTEXTUREFILTERTYPE tex_mag; - switch ((D3DTEXTUREFILTER) Value) + switch (Value) { case D3DFILTER_NEAREST: + case D3DFILTER_MIPNEAREST: case D3DFILTER_LINEARMIPNEAREST: tex_mag = WINED3DTEXF_POINT; break; case D3DFILTER_LINEAR: + case D3DFILTER_MIPLINEAR: case D3DFILTER_LINEARMIPLINEAR: tex_mag = WINED3DTEXF_LINEAR; break; default: + tex_mag = WINED3DTEXF_POINT; ERR("Unhandled texture mag %d !\n",Value); + break; } hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, @@ -2666,24 +2733,26 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, case D3DRENDERSTATE_TEXTUREMIN: { - WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT; - WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE; + WINED3DTEXTUREFILTERTYPE tex_min; + WINED3DTEXTUREFILTERTYPE tex_mip; switch ((D3DTEXTUREFILTER) Value) { case D3DFILTER_NEAREST: tex_min = WINED3DTEXF_POINT; + tex_mip = WINED3DTEXF_NONE; break; case D3DFILTER_LINEAR: tex_min = WINED3DTEXF_LINEAR; + tex_mip = WINED3DTEXF_NONE; break; case D3DFILTER_MIPNEAREST: tex_min = WINED3DTEXF_POINT; tex_mip = WINED3DTEXF_POINT; break; case D3DFILTER_MIPLINEAR: - tex_min = WINED3DTEXF_POINT; - tex_mip = WINED3DTEXF_LINEAR; + tex_min = WINED3DTEXF_LINEAR; + tex_mip = WINED3DTEXF_POINT; break; case D3DFILTER_LINEARMIPNEAREST: tex_min = WINED3DTEXF_POINT; @@ -2696,11 +2765,13 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, default: ERR("Unhandled texture min %d !\n",Value); + tex_min = WINED3DTEXF_POINT; + tex_mip = WINED3DTEXF_NONE; + break; } - IWineD3DDevice_SetSamplerState(This->wineD3DDevice, - 0, WINED3DSAMP_MIPFILTER, - tex_mip); + IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + 0, WINED3DSAMP_MIPFILTER, tex_mip); hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, 0, WINED3DSAMP_MINFILTER, tex_min); @@ -2723,9 +2794,22 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, Value); break; - default: + case D3DRENDERSTATE_BORDERCOLOR: + /* This should probably just forward to the corresponding sampler + * state. Needs tests. */ + FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n"); + hr = E_NOTIMPL; + break; - /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */ + default: + if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 + && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31) + { + FIXME("Unhandled stipple pattern render state (%#x).\n", + RenderStateType); + hr = E_NOTIMPL; + break; + } hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice, RenderStateType, diff --git a/dll/directx/wine/ddraw/direct3d.c b/dll/directx/wine/ddraw/direct3d.c index 80052adb83f..3f2410fe8a7 100644 --- a/dll/directx/wine/ddraw/direct3d.c +++ b/dll/directx/wine/ddraw/direct3d.c @@ -1273,6 +1273,7 @@ IDirect3DImpl_GetCaps(IWineD3D *WineD3D, /* Copy the results into the d3d7 and d3d3 structures */ Desc7->dwDevCaps = WCaps.DevCaps; + Desc7->dpcLineCaps.dwMiscCaps = WCaps.PrimitiveMiscCaps; Desc7->dpcLineCaps.dwRasterCaps = WCaps.RasterCaps; Desc7->dpcLineCaps.dwZCmpCaps = WCaps.ZCmpCaps; Desc7->dpcLineCaps.dwSrcBlendCaps = WCaps.SrcBlendCaps; diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c index 2f426881cba..29fd65e25a9 100644 --- a/dll/directx/wine/ddraw/executebuffer.c +++ b/dll/directx/wine/ddraw/executebuffer.c @@ -489,7 +489,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX)); } else { - ERR("Unhandled vertex processing !\n"); + ERR("Unhandled vertex processing flag %#x.\n", ci->dwFlags); } instr += size; @@ -703,7 +703,6 @@ IDirect3DExecuteBufferImpl_Lock(IDirect3DExecuteBuffer *iface, TRACE("(%p)->(%p)\n", This, lpDesc); dwSize = lpDesc->dwSize; - memset(lpDesc, 0, dwSize); memcpy(lpDesc, &This->desc, dwSize); if (TRACE_ON(d3d7)) { @@ -789,7 +788,6 @@ IDirect3DExecuteBufferImpl_GetExecuteData(IDirect3DExecuteBuffer *iface, TRACE("(%p)->(%p): stub!\n", This, lpData); dwSize = lpData->dwSize; - memset(lpData, 0, dwSize); memcpy(lpData, &This->data, dwSize); if (TRACE_ON(d3d7)) { diff --git a/dll/directx/wine/ddraw/main.c b/dll/directx/wine/ddraw/main.c index bc23987ed81..72426cdf26c 100644 --- a/dll/directx/wine/ddraw/main.c +++ b/dll/directx/wine/ddraw/main.c @@ -288,7 +288,7 @@ err_out: /* Let's hope we never need this ;) */ if(wineD3DDevice) IWineD3DDevice_Release(wineD3DDevice); if(wineD3D) IWineD3D_Release(wineD3D); - if(This) HeapFree(GetProcessHeap(), 0, This->decls); + HeapFree(GetProcessHeap(), 0, This->decls); HeapFree(GetProcessHeap(), 0, This); return hr; } diff --git a/dll/directx/wine/ddraw/material.c b/dll/directx/wine/ddraw/material.c index 6f162f7c828..d75501ecd95 100644 --- a/dll/directx/wine/ddraw/material.c +++ b/dll/directx/wine/ddraw/material.c @@ -294,7 +294,6 @@ IDirect3DMaterialImpl_GetMaterial(IDirect3DMaterial3 *iface, /* Copies the material structure */ EnterCriticalSection(&ddraw_cs); dwSize = lpMat->dwSize; - memset(lpMat, 0, dwSize); memcpy(lpMat, &This->mat, dwSize); LeaveCriticalSection(&ddraw_cs); diff --git a/dll/directx/wine/ddraw/utils.c b/dll/directx/wine/ddraw/utils.c index cfb04049770..5166b167b4a 100644 --- a/dll/directx/wine/ddraw/utils.c +++ b/dll/directx/wine/ddraw/utils.c @@ -171,7 +171,7 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, DDPixelFormat->u2.dwRBitMask = 0x00E0; DDPixelFormat->u3.dwGBitMask = 0x001C; DDPixelFormat->u4.dwBBitMask = 0x0003; - DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0xFF00; break; case WINED3DFMT_B4G4R4X4_UNORM: @@ -182,7 +182,7 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, DDPixelFormat->u3.dwGBitMask = 0x00F0; DDPixelFormat->u4.dwBBitMask = 0x000F; DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; - return; + break; /* How are Z buffer bit depth and Stencil buffer bit depth related? */ @@ -236,8 +236,8 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, DDPixelFormat->u3.dwZBitMask = 0x00FFFFFFFF; DDPixelFormat->u4.dwStencilBitMask = 0x00000000; DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; - break; + case WINED3DFMT_S1_UINT_D15_UNORM: DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER; DDPixelFormat->dwFourCC = 0; diff --git a/dll/directx/wine/wined3d/arb_program_shader.c b/dll/directx/wine/wined3d/arb_program_shader.c index cf7638605eb..0824fedb571 100644 --- a/dll/directx/wine/wined3d/arb_program_shader.c +++ b/dll/directx/wine/wined3d/arb_program_shader.c @@ -39,8 +39,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_constants); WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - /* Extract a line. Note that this modifies the source string. */ static char *get_line(char **ptr) { @@ -61,14 +59,14 @@ static char *get_line(char **ptr) static void shader_arb_dump_program_source(const char *source) { - unsigned long source_size; + ULONG source_size; char *ptr, *line, *tmp; source_size = strlen(source) + 1; tmp = HeapAlloc(GetProcessHeap(), 0, source_size); if (!tmp) { - ERR("Failed to allocate %lu bytes for shader source.\n", source_size); + ERR("Failed to allocate %u bytes for shader source.\n", source_size); return; } memcpy(tmp, source, source_size); @@ -81,10 +79,13 @@ static void shader_arb_dump_program_source(const char *source) } /* GL locking for state handlers is done by the caller. */ -static BOOL need_mova_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info) +static BOOL need_rel_addr_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info) { - IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) shader; - if(!This->baseShader.reg_maps.usesmova) return FALSE; + if (shader->baseShader.reg_maps.shader_version.type == WINED3D_SHADER_TYPE_VERTEX) + { + if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) return TRUE; + } + if (!shader->baseShader.reg_maps.usesmova) return FALSE; return !gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]; } @@ -95,29 +96,85 @@ static inline BOOL use_nv_clip(const struct wined3d_gl_info *gl_info) && !(gl_info->quirks & WINED3D_QUIRK_NV_CLIP_BROKEN); } -static BOOL need_helper_const(const struct wined3d_gl_info *gl_info) +static BOOL need_helper_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info) { - if (!gl_info->supported[NV_VERTEX_PROGRAM] /* Need to init colors. */ - || gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT /* Load the immval offset. */ - || gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W /* Have to init texcoords. */ - || (!use_nv_clip(gl_info)) /* Init the clip texcoord */) - { - return TRUE; - } + if (need_rel_addr_const(shader, gl_info)) return TRUE; + if (!gl_info->supported[NV_VERTEX_PROGRAM]) return TRUE; /* Need to init colors. */ + if (gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT) return TRUE; /* Load the immval offset. */ + if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) return TRUE; /* Have to init texcoords. */ + if (!use_nv_clip(gl_info)) return TRUE; /* Init the clip texcoord */ + if (shader->baseShader.reg_maps.usesnrm) return TRUE; /* 0.0 */ + if (shader->baseShader.reg_maps.usesrcp) return TRUE; /* EPS */ return FALSE; } -static unsigned int reserved_vs_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info) +static unsigned int reserved_vs_const(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info) { unsigned int ret = 1; /* We use one PARAM for the pos fixup, and in some cases one to load * some immediate values into the shader */ - if(need_helper_const(gl_info)) ret++; - if(need_mova_const(shader, gl_info)) ret++; + if(need_helper_const(shader, gl_info)) ret++; + if(need_rel_addr_const(shader, gl_info)) ret++; return ret; } +enum arb_helper_value +{ + ARB_ZERO, + ARB_ONE, + ARB_TWO, + ARB_0001, + ARB_EPS, + + ARB_VS_REL_OFFSET +}; + +static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum arb_helper_value value) +{ + if (shader == WINED3D_SHADER_TYPE_GEOMETRY) + { + ERR("Geometry shaders are unsupported\n"); + return "bad"; + } + + if (shader == WINED3D_SHADER_TYPE_PIXEL) + { + switch (value) + { + case ARB_ZERO: return "ps_helper_const.x"; + case ARB_ONE: return "ps_helper_const.y"; + case ARB_TWO: return "coefmul.x"; + case ARB_0001: return "helper_const.xxxy"; + case ARB_EPS: return "ps_helper_const.z"; + default: break; + } + } + else + { + switch (value) + { + case ARB_ZERO: return "helper_const.x"; + case ARB_ONE: return "helper_const.y"; + case ARB_TWO: return "helper_const.z"; + case ARB_EPS: return "helper_const.w"; + case ARB_0001: return "helper_const.xxxy"; + case ARB_VS_REL_OFFSET: return "rel_addr_const.y"; + } + } + FIXME("Unmanaged %s shader helper constant requested: %u\n", + shader == WINED3D_SHADER_TYPE_PIXEL ? "pixel" : "vertex", value); + switch (value) + { + case ARB_ZERO: return "0.0"; + case ARB_ONE: return "1.0"; + case ARB_TWO: return "2.0"; + case ARB_0001: return "{0.0, 0.0, 0.0, 1.0}"; + case ARB_EPS: return "1e-8"; + default: return "bad"; + } +} + static inline BOOL ffp_clip_emul(IWineD3DStateBlockImpl *stateblock) { return stateblock->lowest_disabled_stage < 7; @@ -287,7 +344,8 @@ struct shader_arb_priv const struct arb_ps_compiled_shader *compiled_fprog; const struct arb_vs_compiled_shader *compiled_vprog; GLuint depth_blt_vprogram_id; - GLuint depth_blt_fprogram_id[tex_type_count]; + GLuint depth_blt_fprogram_id_full[tex_type_count]; + GLuint depth_blt_fprogram_id_masked[tex_type_count]; BOOL use_arbfp_fixed_func; struct wine_rb_tree fragment_shaders; BOOL last_ps_const_clamped; @@ -509,7 +567,7 @@ static inline void shader_arb_ps_local_constants(IWineD3DDeviceImpl* deviceImpl) */ float val[4]; val[0] = context->render_offscreen ? 0.0f - : ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height; + : deviceImpl->render_targets[0]->currentDesc.Height; val[1] = context->render_offscreen ? 1.0f : -1.0f; val[2] = 1.0f; val[3] = 0.0f; @@ -576,7 +634,7 @@ static inline void shader_arb_vs_local_constants(IWineD3DDeviceImpl* deviceImpl) /* GL locking is done by the caller (state handler) */ static void shader_arb_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; + IWineD3DDeviceImpl *device = context->swapchain->device; IWineD3DStateBlockImpl* stateBlock = device->stateBlock; const struct wined3d_gl_info *gl_info = context->gl_info; @@ -606,7 +664,7 @@ static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return; + if (!context || context->swapchain->device != This) return; memset(context->vshader_const_dirty + start, 1, sizeof(*context->vshader_const_dirty) * count); This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count); @@ -619,7 +677,7 @@ static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active * context. On a context switch the old context will be fully dirtified */ - if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.device != This) return; + if (!context || context->swapchain->device != This) return; memset(context->pshader_const_dirty + start, 1, sizeof(*context->pshader_const_dirty) * count); This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count); @@ -670,12 +728,23 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s if (pshader) { max_constantsF = gl_info->limits.arb_ps_native_constants; + /* 24 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value. */ + if (max_constantsF < 24) + max_constantsF = gl_info->limits.arb_ps_float_constants; } else { + max_constantsF = gl_info->limits.arb_vs_native_constants; + /* 96 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value. + * Also prevents max_constantsF from becoming less than 0 and + * wrapping . */ + if (max_constantsF < 96) + max_constantsF = gl_info->limits.arb_vs_float_constants; + if(This->baseShader.reg_maps.usesrelconstF) { DWORD highest_constf = 0, clip_limit; - max_constantsF = gl_info->limits.arb_vs_native_constants - reserved_vs_const(iface, gl_info); + + max_constantsF -= reserved_vs_const(This, gl_info); max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants); for(i = 0; i < This->baseShader.limits.constant_float; i++) @@ -708,7 +777,6 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s { if (ctx->target_version >= NV2) *num_clipplanes = gl_info->limits.clipplanes; else *num_clipplanes = min(gl_info->limits.clipplanes, 4); - max_constantsF = gl_info->limits.arb_vs_native_constants; } } @@ -1355,7 +1423,9 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD if (pshader) { gen_color_correction(buffer, dst_str, ins->dst[0].write_mask, - "one", "coefmul.x", priv->cur_ps_args->super.color_fixup[sampler_idx]); + arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_ONE), + arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_TWO), + priv->cur_ps_args->super.color_fixup[sampler_idx]); } } @@ -1369,6 +1439,8 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in int insert_line; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data; + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); + const char *two = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_TWO); /* Assume a new line will be added */ insert_line = 1; @@ -1394,13 +1466,13 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in shader_addline(buffer, "ADD T%c, -%s, coefdiv.x;\n", 'A' + tmpreg, regstr); break; case WINED3DSPSM_SIGN: - shader_addline(buffer, "MAD T%c, %s, coefmul.x, -one.x;\n", 'A' + tmpreg, regstr); + shader_addline(buffer, "MAD T%c, %s, %s, -%s;\n", 'A' + tmpreg, regstr, two, one); break; case WINED3DSPSM_SIGNNEG: - shader_addline(buffer, "MAD T%c, %s, -coefmul.x, one.x;\n", 'A' + tmpreg, regstr); + shader_addline(buffer, "MAD T%c, %s, %s, %s;\n", 'A' + tmpreg, regstr, two, one); break; case WINED3DSPSM_COMP: - shader_addline(buffer, "SUB T%c, one.x, %s;\n", 'A' + tmpreg, regstr); + shader_addline(buffer, "SUB T%c, %s, %s;\n", 'A' + tmpreg, one, regstr); break; case WINED3DSPSM_X2: shader_addline(buffer, "ADD T%c, %s, %s;\n", 'A' + tmpreg, regstr, regstr); @@ -1671,12 +1743,16 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; BOOL pshader = shader_is_pshader_version(shader->baseShader.reg_maps.shader_version.type); struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data; + const char *zero = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_ZERO); + const char *one = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_ONE); + const char *two = arb_get_helper_value(shader->baseShader.reg_maps.shader_version.type, ARB_TWO); struct wined3d_shader_buffer *buffer = ins->ctx->buffer; char src0_param[256]; if(ins->handler_idx == WINED3DSIH_MOVA) { char write_mask[6]; + const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET); if(ctx->target_version >= NV2) { shader_hw_map2gl(ins); @@ -1695,15 +1771,15 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) * The ARL is performed when A0 is used - the requested component is read from A0_SHADOW into * A0.x. We can use the overwritten component of A0_shadow as temporary storage for the sign. */ - shader_addline(buffer, "SGE A0_SHADOW%s, %s, mova_const.y;\n", write_mask, src0_param); - shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, mova_const.z, -mova_const.w;\n", write_mask); + shader_addline(buffer, "SGE A0_SHADOW%s, %s, %s;\n", write_mask, src0_param, zero); + shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, %s, -%s;\n", write_mask, two, one); shader_addline(buffer, "ABS TA%s, %s;\n", write_mask, src0_param); - shader_addline(buffer, "ADD TA%s, TA, mova_const.x;\n", write_mask); + shader_addline(buffer, "ADD TA%s, TA, rel_addr_const.x;\n", write_mask); shader_addline(buffer, "FLR TA%s, TA;\n", write_mask); if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) { - shader_addline(buffer, "ADD TA%s, TA, helper_const.z;\n", write_mask); + shader_addline(buffer, "ADD TA%s, TA, %s;\n", write_mask, offset); } shader_addline(buffer, "MUL A0_SHADOW%s, TA, A0_SHADOW;\n", write_mask); @@ -1715,8 +1791,9 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) src0_param[0] = '\0'; if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) { + const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET); shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param); - shader_addline(buffer, "ADD TA.x, %s, helper_const.z;\n", src0_param); + shader_addline(buffer, "ADD TA.x, %s, %s;\n", src0_param, offset); shader_addline(buffer, "ARL A0.x, TA.x;\n"); } else @@ -2170,6 +2247,8 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) const struct wined3d_shader_dst_param *dst = &ins->dst[0]; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; char dst_name[50]; + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); /* texdepth has an implicit destination, the fragment depth value. It's only parameter, * which is essentially an input, is the destination register because it is the first @@ -2181,7 +2260,7 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) /* According to the msdn, the source register(must be r5) is unusable after * the texdepth instruction, so we're free to modify it */ - shader_addline(buffer, "MIN %s.y, %s.y, one.y;\n", dst_name, dst_name); + shader_addline(buffer, "MIN %s.y, %s.y, %s;\n", dst_name, dst_name, one); /* How to deal with the special case dst_name.g == 0? if r != 0, then * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct @@ -2189,8 +2268,8 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) */ shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name); shader_addline(buffer, "MUL TA.x, %s.x, %s.y;\n", dst_name, dst_name); - shader_addline(buffer, "MIN TA.x, TA.x, one.x;\n"); - shader_addline(buffer, "MAX result.depth, TA.x, 0.0;\n"); + shader_addline(buffer, "MIN TA.x, TA.x, %s;\n", one); + shader_addline(buffer, "MAX result.depth, TA.x, %s;\n", zero); } /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB: @@ -2254,6 +2333,8 @@ static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins const struct wined3d_shader_dst_param *dst = &ins->dst[0]; char src0[50], dst_name[50]; BOOL is_color; + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); shader_arb_get_src_param(ins, &ins->src[0], 0, src0); shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color); @@ -2265,8 +2346,8 @@ static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins */ shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name); shader_addline(buffer, "MUL %s.x, %s.x, %s.y;\n", dst_name, dst_name, dst_name); - shader_addline(buffer, "MIN %s.x, %s.x, one.x;\n", dst_name, dst_name); - shader_addline(buffer, "MAX result.depth, %s.x, 0.0;\n", dst_name); + shader_addline(buffer, "MIN %s.x, %s.x, %s;\n", dst_name, dst_name, one); + shader_addline(buffer, "MAX result.depth, %s.x, %s;\n", dst_name, zero); } /** Handles transforming all WINED3DSIO_M?x? opcodes for @@ -2325,6 +2406,44 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins) } } +static void shader_hw_rcp(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_shader_buffer *buffer = ins->ctx->buffer; + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; + const char *flt_eps = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_EPS); + + char dst[50]; + char src[50]; + + shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */ + shader_arb_get_src_param(ins, &ins->src[0], 0, src); + if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE) + { + /* Dx sdk says .x is used if no swizzle is given, but our test shows that + * .w is used + */ + strcat(src, ".w"); + } + + /* TODO: If the destination is readable, and not the same as the source, the destination + * can be used instead of TA + */ + if (priv->target_version >= NV2) + { + shader_addline(buffer, "MOVC TA.x, %s;\n", src); + shader_addline(buffer, "MOV TA.x (EQ.x), %s;\n", flt_eps); + shader_addline(buffer, "RCP%s %s, TA.x;\n", shader_arb_get_modifier(ins), dst); + } + else + { + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); + shader_addline(buffer, "ABS TA.x, %s;\n", src); + shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero); + shader_addline(buffer, "MAD TA.x, TA.y, %s, %s;\n", flt_eps, src); + shader_addline(buffer, "RCP%s %s, TA.x;\n", shader_arb_get_modifier(ins), dst); + } +} + static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins) { struct wined3d_shader_buffer *buffer = ins->ctx->buffer; @@ -2364,20 +2483,44 @@ static void shader_hw_nrm(const struct wined3d_shader_instruction *ins) char src_name[50]; struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type); + const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO); shader_arb_get_dst_param(ins, &ins->dst[0], dst_name); shader_arb_get_src_param(ins, &ins->src[0], 1 /* Use TB */, src_name); + /* In D3D, NRM of a vector with length zero returns zero. Catch this situation, as + * otherwise NRM or RSQ would return NaN */ if(pshader && priv->target_version >= NV3) { + /* GL_NV_fragment_program2's NRM needs protection against length zero vectors too + * + * TODO: Find out if DP3+NRM+MOV is really faster than DP3+RSQ+MUL + */ + shader_addline(buffer, "DP3C TA, %s, %s;\n", src_name, src_name); shader_addline(buffer, "NRM%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name); + shader_addline(buffer, "MOV %s (EQ), %s;\n", dst_name, zero); + } + else if(priv->target_version >= NV2) + { + shader_addline(buffer, "DP3C TA.x, %s, %s;\n", src_name, src_name); + shader_addline(buffer, "RSQ TA.x (NE), TA.x;\n"); + shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name, + src_name); } else { - shader_addline(buffer, "DP3 TA, %s, %s;\n", src_name, src_name); - shader_addline(buffer, "RSQ TA, TA.x;\n"); + const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE); + + shader_addline(buffer, "DP3 TA.x, %s, %s;\n", src_name, src_name); + /* Pass any non-zero value to RSQ if the input vector has a length of zero. The + * RSQ result doesn't matter, as long as multiplying it by 0 returns 0. + */ + shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero); + shader_addline(buffer, "MAD TA.x, %s, TA.y, TA.x;\n", one); + + shader_addline(buffer, "RSQ TA.x, TA.x;\n"); /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/ - shader_addline(buffer, "MUL%s %s, %s, TA;\n", shader_arb_get_modifier(ins), dst_name, + shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name, src_name); } } @@ -2997,6 +3140,7 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh { unsigned int cur_clip = 0; char component[4] = {'x', 'y', 'z', 'w'}; + const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO); for (i = 0; i < gl_info->limits.clipplanes; ++i) { @@ -3009,16 +3153,16 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh switch(cur_clip) { case 0: - shader_addline(buffer, "MOV TA, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA, %s;\n", zero); break; case 1: - shader_addline(buffer, "MOV TA.yzw, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA.yzw, %s;\n", zero); break; case 2: - shader_addline(buffer, "MOV TA.zw, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA.zw, %s;\n", zero); break; case 3: - shader_addline(buffer, "MOV TA.w, -helper_const.w;\n"); + shader_addline(buffer, "MOV TA.w, %s;\n", zero); break; } shader_addline(buffer, "MOV result.texcoord[%u], TA;\n", @@ -3028,8 +3172,9 @@ static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_sh /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c * and the glsl equivalent */ - if(need_helper_const(gl_info)) { - shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, helper_const.x, -TMP_OUT.w;\n"); + if(need_helper_const((IWineD3DBaseShaderImpl *) This, gl_info)) { + const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); + shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); } else { shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); @@ -3103,12 +3248,14 @@ static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_inf } /* GL locking is done by the caller */ -static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, enum tex_types tex_type) +static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, + enum tex_types tex_type, BOOL masked) { GLuint program_id = 0; + const char *fprogram; GLint pos; - static const char * const blt_fprograms[tex_type_count] = + static const char * const blt_fprograms_full[tex_type_count] = { /* tex_1d */ NULL, @@ -3134,16 +3281,55 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i "END\n", }; - if (!blt_fprograms[tex_type]) + static const char * const blt_fprograms_masked[tex_type_count] = { - FIXME("tex_type %#x not supported\n", tex_type); + /* tex_1d */ + NULL, + /* tex_2d */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + /* tex_3d */ + NULL, + /* tex_cube */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + /* tex_rect */ + "!!ARBfp1.0\n" + "PARAM mask = program.local[0];\n" + "TEMP R0;\n" + "SLT R0.xy, fragment.position, mask.zwzw;\n" + "MUL R0.x, R0.x, R0.y;\n" + "KIL -R0.x;\n" + "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n" + "MOV result.depth.z, R0.x;\n" + "END\n", + }; + + fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; + if (!fprogram) + { + FIXME("tex_type %#x not supported, falling back to tex_2d\n", tex_type); tex_type = tex_2d; + fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type]; } GL_EXTCALL(glGenProgramsARB(1, &program_id)); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id)); - GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(blt_fprograms[tex_type]), blt_fprograms[tex_type])); + GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fprogram), fprogram)); checkGLcall("glProgramStringARB()"); glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos); @@ -3151,7 +3337,7 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i { FIXME("Fragment program error at position %d: %s\n\n", pos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB))); - shader_arb_dump_program_source(blt_fprograms[tex_type]); + shader_arb_dump_program_source(fprogram); } else { @@ -3309,7 +3495,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct char fragcolor[16]; DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This), next_local, cur; struct shader_arb_ctx_priv priv_ctx; - BOOL dcl_tmp = args->super.srgb_correction, dcl_td = FALSE; + BOOL dcl_td = FALSE; BOOL want_nv_prog = FALSE; struct arb_pshader_private *shader_priv = This->baseShader.backend_data; GLint errPos; @@ -3331,7 +3517,6 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct } switch(found) { - case 4: dcl_tmp = FALSE; break; case 0: sprintf(srgbtmp[0], "TA"); sprintf(srgbtmp[1], "TB"); @@ -3351,6 +3536,8 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct case 3: sprintf(srgbtmp[3], "TA"); break; + case 4: + break; } /* Create the hw ARB shader */ @@ -3432,7 +3619,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */ shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n"); shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n"); - shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n"); + shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %1.10f, 0.0 };\n", eps); if (reg_maps->shader_version.major < 2) { @@ -3927,11 +4114,11 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShaderImpl *This, struct } shader_addline(buffer, "TEMP TMP_OUT;\n"); - if(need_helper_const(gl_info)) { - shader_addline(buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset); + if(need_helper_const((IWineD3DBaseShaderImpl *) This, gl_info)) { + shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %1.10f};\n", eps); } - if(need_mova_const((IWineD3DBaseShader *) This, gl_info)) { - shader_addline(buffer, "PARAM mova_const = { 0.5, 0.0, 2.0, 1.0 };\n"); + if(need_rel_addr_const((IWineD3DBaseShaderImpl *) This, gl_info)) { + shader_addline(buffer, "PARAM rel_addr_const = { 0.5, %d.0, 0.0, 0.0 };\n", This->rel_offset); shader_addline(buffer, "TEMP A0_SHADOW;\n"); } @@ -3979,15 +4166,18 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShaderImpl *This, struct */ if (!gl_info->supported[NV_VERTEX_PROGRAM]) { - shader_addline(buffer, "MOV result.color.secondary, -helper_const.wwwy;\n"); + const char *color_init = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_0001); + shader_addline(buffer, "MOV result.color.secondary, %s;\n", color_init); if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W && !device->frag_pipe->ffp_proj_control) { int i; - for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) { - if(This->baseShader.reg_maps.texcoord_mask[i] != 0 && + const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE); + for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) + { + if (This->baseShader.reg_maps.texcoord_mask[i] != 0 && This->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) { - shader_addline(buffer, "MOV result.texcoord[%u].w, -helper_const.y;\n", i); + shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one); } } } @@ -4339,7 +4529,7 @@ static inline void find_arb_vs_compile_args(IWineD3DVertexShaderImpl *shader, IW /* GL locking is done by the caller */ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) { - IWineD3DDeviceImpl *This = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; + IWineD3DDeviceImpl *This = context->swapchain->device; struct shader_arb_priv *priv = This->shader_priv; const struct wined3d_gl_info *gl_info = context->gl_info; int i; @@ -4443,18 +4633,23 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, } /* GL locking is done by the caller */ -static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { +static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) +{ + const float mask[] = {0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy}; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_arb_priv *priv = This->shader_priv; - GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type]; const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + GLuint *blt_fprogram; if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info); GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id)); glEnable(GL_VERTEX_PROGRAM_ARB); - if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type); + blt_fprogram = masked ? &priv->depth_blt_fprogram_id_masked[tex_type] : &priv->depth_blt_fprogram_id_full[tex_type]; + if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type, masked); GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *blt_fprogram)); + if (masked) GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, mask)); glEnable(GL_FRAGMENT_PROGRAM_ARB); } @@ -4499,7 +4694,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { if (shader_data->num_gl_shaders) { - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); for (i = 0; i < shader_data->num_gl_shaders; ++i) @@ -4525,7 +4720,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) { if (shader_data->num_gl_shaders) { - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); for (i = 0; i < shader_data->num_gl_shaders; ++i) @@ -4594,9 +4789,15 @@ static void shader_arb_free(IWineD3DDevice *iface) { if(priv->depth_blt_vprogram_id) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id)); } - for (i = 0; i < tex_type_count; ++i) { - if (priv->depth_blt_fprogram_id[i]) { - GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i])); + for (i = 0; i < tex_type_count; ++i) + { + if (priv->depth_blt_fprogram_id_full[i]) + { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_full[i])); + } + if (priv->depth_blt_fprogram_id_masked[i]) + { + GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_masked[i])); } } LEAVE_GL(); @@ -4611,16 +4812,19 @@ static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) { static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps) { - DWORD vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants); - DWORD ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants); - - /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps, - * then overwrite the shader specific ones - */ - none_shader_backend.shader_get_caps(gl_info, pCaps); - if (gl_info->supported[ARB_VERTEX_PROGRAM]) { + DWORD vs_consts; + + /* 96 is the minimum allowed value of MAX_PROGRAM_ENV_PARAMETERS_ARB + * for vertex programs. If the native limit is less than that it's + * not very useful, and e.g. Mesa swrast returns 0, probably to + * indicate it's a software implementation. */ + if (gl_info->limits.arb_vs_native_constants < 96) + vs_consts = gl_info->limits.arb_vs_float_constants; + else + vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants); + if (gl_info->supported[NV_VERTEX_PROGRAM3]) { pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0); @@ -4639,9 +4843,23 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh } pCaps->MaxVertexShaderConst = vs_consts; } + else + { + pCaps->VertexShaderVersion = 0; + pCaps->MaxVertexShaderConst = 0; + } if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) { + DWORD ps_consts; + + /* Similar as above for vertex programs, but the minimum for fragment + * programs is 24. */ + if (gl_info->limits.arb_ps_native_constants < 24) + ps_consts = gl_info->limits.arb_ps_float_constants; + else + ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants); + if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) { pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0); @@ -4661,6 +4879,12 @@ static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct sh pCaps->PixelShader1xMaxValue = 8.0f; pCaps->MaxPixelShaderConst = ps_consts; } + else + { + pCaps->PixelShaderVersion = 0; + pCaps->PixelShader1xMaxValue = 0.0f; + pCaps->MaxPixelShaderConst = 0; + } pCaps->VSClipping = use_nv_clip(gl_info); } @@ -4766,7 +4990,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL /* WINED3DSIH_NRM */ shader_hw_nrm, /* WINED3DSIH_PHASE */ NULL, /* WINED3DSIH_POW */ shader_hw_log_pow, - /* WINED3DSIH_RCP */ shader_hw_scalar_op, + /* WINED3DSIH_RCP */ shader_hw_rcp, /* WINED3DSIH_REP */ shader_hw_rep, /* WINED3DSIH_RET */ shader_hw_ret, /* WINED3DSIH_RSQ */ shader_hw_scalar_op, @@ -5279,6 +5503,7 @@ static void arbfp_free(IWineD3DDevice *iface) { static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) { + caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE | WINED3DTEXOPCAPS_SELECTARG1 | WINED3DTEXOPCAPS_SELECTARG2 | @@ -5309,14 +5534,11 @@ static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen caps->MaxTextureBlendStages = 8; caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8); - - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; } -#undef GLINFO_LOCATION -#define GLINFO_LOCATION stateblock->device->adapter->gl_info static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float col[4]; @@ -5338,6 +5560,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float col[4]; @@ -5366,6 +5589,7 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float mat[2][2]; @@ -5377,9 +5601,8 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled * anyway */ - if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) { - device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context); - } + if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) + stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context); } if(device->shader_backend == &arb_program_shader_backend) { @@ -5403,6 +5626,7 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; float param[4]; @@ -5414,9 +5638,8 @@ static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock /* The pixel shader has to know the luminance offset. Do a constants update if it * isn't scheduled anyway */ - if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) { - device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context); - } + if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) + stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context); } if(device->shader_backend == &arb_program_shader_backend) { @@ -5648,9 +5871,9 @@ static void gen_ffp_instr(struct wined3d_shader_buffer *buffer, unsigned int sta } } -/* The stateblock is passed for GLINFO_LOCATION */ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock) { + const struct wined3d_gl_info *gl_info = &stateblock->device->adapter->gl_info; unsigned int stage; struct wined3d_shader_buffer buffer; BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; @@ -5925,6 +6148,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *device = stateblock->device; struct shader_arb_priv *priv = device->fragment_priv; BOOL use_pshader = use_ps(stateblock); @@ -5961,7 +6185,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, return; } new_desc->num_textures_used = 0; - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { if(settings.op[i].cop == WINED3DTOP_DISABLE) break; new_desc->num_textures_used = i; @@ -6007,13 +6231,10 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) { device->shader_backend->shader_select(context, use_pshader, use_vshader); - if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) { - device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context); - } - } - if(use_pshader) { - device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONSTANT, stateblock, context); + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) + stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context); } + if (use_pshader) stateblock_apply_state(STATE_PIXELSHADERCONSTANT, stateblock, context); } /* We can't link the fog states to the fragment state directly since the vertex pipeline links them @@ -6060,130 +6281,128 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } } -#undef GLINFO_LOCATION - static const struct StateEntryTemplate arbfp_fragmentstate_template[] = { {STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -6194,11 +6413,11 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = { {STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE }, {STATE_PIXELSHADER, { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, WINED3D_GL_EXT_NONE }, @@ -6223,13 +6442,12 @@ const struct fragment_pipeline arbfp_fragment_pipeline = { TRUE /* We can disable projected textures */ }; -#define GLINFO_LOCATION device->adapter->gl_info - struct arbfp_blit_priv { GLenum yuy2_rect_shader, yuy2_2d_shader; GLenum uyvy_rect_shader, uyvy_2d_shader; GLenum yv12_rect_shader, yv12_2d_shader; GLenum p8_rect_shader, p8_2d_shader; + GLuint palette_texture; }; static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) { @@ -6245,6 +6463,7 @@ static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) { /* Context activation is done by the caller. */ static void arbfp_blit_free(IWineD3DDevice *iface) { IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct arbfp_blit_priv *priv = device->blit_priv; ENTER_GL(); @@ -6257,6 +6476,8 @@ static void arbfp_blit_free(IWineD3DDevice *iface) { GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader)); GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader)); checkGLcall("Delete yuv and p8 programs"); + + if(priv->palette_texture) glDeleteTextures(1, &priv->palette_texture); LEAVE_GL(); HeapFree(GetProcessHeap(), 0, device->blit_priv); @@ -6499,6 +6720,7 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype) { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; GLenum shader; struct wined3d_shader_buffer buffer; struct arbfp_blit_priv *priv = device->blit_priv; @@ -6563,9 +6785,43 @@ static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype) return shader; } +/* Context activation is done by the caller. */ +static void upload_palette(IWineD3DSurfaceImpl *surface) +{ + BYTE table[256][4]; + IWineD3DDeviceImpl *device = surface->resource.device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct arbfp_blit_priv *priv = device->blit_priv; + BOOL colorkey = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) ? TRUE : FALSE; + + d3dfmt_p8_init_palette(surface, table, colorkey); + + ENTER_GL(); + if (!priv->palette_texture) + glGenTextures(1, &priv->palette_texture); + + GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1)); + glBindTexture(GL_TEXTURE_1D, priv->palette_texture); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + /* Make sure we have discrete color levels. */ + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + /* Upload the palette */ + /* TODO: avoid unneeed uploads in the future by adding some SFLAG_PALETTE_DIRTY mechanism */ + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table); + + /* Switch back to unit 0 in which the 2D texture will be stored. */ + GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0)); + LEAVE_GL(); +} + /* Context activation is done by the caller. */ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_fixup, GLenum textype) { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; GLenum shader; struct wined3d_shader_buffer buffer; char luminance_component; @@ -6720,19 +6976,20 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_ } /* Context activation is done by the caller. */ -static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, - GLenum textype, UINT width, UINT height) +static HRESULT arbfp_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface) { GLenum shader; IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; - float size[4] = {width, height, 1, 1}; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + float size[4] = {surface->pow2Width, surface->pow2Height, 1, 1}; struct arbfp_blit_priv *priv = device->blit_priv; enum complex_fixup fixup; + GLenum textype = surface->texture_target; - if (!is_complex_fixup(format_desc->color_fixup)) + if (!is_complex_fixup(surface->resource.format_desc->color_fixup)) { TRACE("Fixup:\n"); - dump_color_fixup_desc(format_desc->color_fixup); + dump_color_fixup_desc(surface->resource.format_desc->color_fixup); /* Don't bother setting up a shader for unconverted formats */ ENTER_GL(); glEnable(textype); @@ -6741,7 +6998,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD return WINED3D_OK; } - fixup = get_complex_fixup(format_desc->color_fixup); + fixup = get_complex_fixup(surface->resource.format_desc->color_fixup); switch(fixup) { @@ -6760,6 +7017,8 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD case COMPLEX_FIXUP_P8: shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader; if (!shader) shader = gen_p8_shader(device, textype); + + upload_palette(surface); break; default: @@ -6808,31 +7067,47 @@ static void arbfp_blit_unset(IWineD3DDevice *iface) { LEAVE_GL(); } -static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup) +static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) { - enum complex_fixup complex_fixup; + enum complex_fixup src_fixup; + if (blit_op != BLIT_OP_BLIT) + { + TRACE("Unsupported blit_op=%d\n", blit_op); + return FALSE; + } + + src_fixup = get_complex_fixup(src_format_desc->color_fixup); if (TRACE_ON(d3d_shader) && TRACE_ON(d3d)) { TRACE("Checking support for fixup:\n"); - dump_color_fixup_desc(fixup); + dump_color_fixup_desc(src_format_desc->color_fixup); } - if (is_identity_fixup(fixup)) + if (!is_identity_fixup(dst_format_desc->color_fixup)) + { + TRACE("Destination fixups are not supported\n"); + return FALSE; + } + + if (is_identity_fixup(src_format_desc->color_fixup)) { TRACE("[OK]\n"); return TRUE; } - /* We only support YUV conversions. */ - if (!is_complex_fixup(fixup)) + /* We only support YUV conversions. */ + if (!is_complex_fixup(src_format_desc->color_fixup)) { TRACE("[FAILED]\n"); return FALSE; } - complex_fixup = get_complex_fixup(fixup); - switch(complex_fixup) + switch(src_fixup) { case COMPLEX_FIXUP_YUY2: case COMPLEX_FIXUP_UYVY: @@ -6842,18 +7117,70 @@ static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup) return TRUE; default: - FIXME("Unsupported YUV fixup %#x\n", complex_fixup); + FIXME("Unsupported YUV fixup %#x\n", src_fixup); TRACE("[FAILED]\n"); return FALSE; } } +HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op, + DWORD Filter) +{ + IWineD3DSwapChainImpl *dst_swapchain; + struct wined3d_context *context; + RECT dst_rect = *dst_rect_in; + + /* Now load the surface */ + surface_internal_preload(src_surface, SRGB_RGB); + + /* Activate the destination context, set it up for blitting */ + context = context_acquire(device, dst_surface); + context_apply_blit_state(context, device); + + /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates', + * while OpenGL coordinates are window relative. + * Also beware of the origin difference(top left vs bottom left). + * Also beware that the front buffer's surface size is screen width x screen height, + * whereas the real gl drawable size is the size of the window. */ + dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL; + if (dst_swapchain && dst_surface == dst_swapchain->front_buffer) + surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); + + arbfp_blit_set((IWineD3DDevice *)device, src_surface); + + ENTER_GL(); + + /* Draw a textured quad */ + draw_textured_quad(src_surface, src_rect, &dst_rect, Filter); + + LEAVE_GL(); + + /* Leave the opengl state valid for blitting */ + arbfp_blit_unset((IWineD3DDevice *)device); + + if (wined3d_settings.strict_draw_ordering || (dst_swapchain + && (dst_surface == dst_swapchain->front_buffer + || dst_swapchain->num_contexts > 1))) + wglFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); + return WINED3D_OK; +} + +static HRESULT arbfp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +{ + FIXME("Color filling not implemented by arbfp_blit\n"); + return WINED3DERR_INVALIDCALL; +} + const struct blit_shader arbfp_blit = { arbfp_blit_alloc, arbfp_blit_free, arbfp_blit_set, arbfp_blit_unset, - arbfp_blit_color_fixup_supported, + arbfp_blit_supported, + arbfp_blit_color_fill }; - -#undef GLINFO_LOCATION diff --git a/dll/directx/wine/wined3d/ati_fragment_shader.c b/dll/directx/wine/wined3d/ati_fragment_shader.c index 0f911e9dc15..993ece0be8d 100644 --- a/dll/directx/wine/wined3d/ati_fragment_shader.c +++ b/dll/directx/wine/wined3d/ati_fragment_shader.c @@ -190,7 +190,6 @@ static const char *debug_mask(GLuint mask) { default: return "Unexpected writemask"; } } -#define GLINFO_LOCATION (*gl_info) static void wrap_op1(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) @@ -796,11 +795,10 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con checkGLcall("GL_EXTCALL(glEndFragmentShaderATI())"); return ret; } -#undef GLINFO_LOCATION -#define GLINFO_LOCATION stateblock->device->adapter->gl_info static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; IWineD3DDeviceImpl *This = stateblock->device; const struct atifs_ffp_desc *desc; struct ffp_frag_settings settings; @@ -818,14 +816,14 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st return; } new_desc->num_textures_used = 0; - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { if(settings.op[i].cop == WINED3DTOP_DISABLE) break; new_desc->num_textures_used = i; } memcpy(&new_desc->parent.settings, &settings, sizeof(settings)); - new_desc->shader = gen_ati_shader(settings.op, context->gl_info); + new_desc->shader = gen_ati_shader(settings.op, gl_info); add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent); TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc); desc = new_desc; @@ -849,6 +847,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); @@ -859,6 +858,7 @@ static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *statebloc static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + const struct wined3d_gl_info *gl_info = context->gl_info; float mat[2][2]; mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]); @@ -907,127 +907,124 @@ static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *statebl if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) { device->shader_backend->shader_select(context, FALSE, use_vshader); - if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) { - device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context); - } + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) + stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context); } } -#undef GLINFO_LOCATION - static const struct StateEntryTemplate atifs_fragmentstate_template[] = { {STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor_atifs }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), set_bumpmat }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -1063,6 +1060,7 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) { static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) { + caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE | WINED3DTEXOPCAPS_SELECTARG1 | WINED3DTEXOPCAPS_SELECTARG2 | @@ -1105,8 +1103,6 @@ static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragmen */ caps->MaxTextureBlendStages = 8; caps->MaxSimultaneousTextures = 6; - - caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; } static HRESULT atifs_alloc(IWineD3DDevice *iface) { @@ -1128,11 +1124,11 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } -#define GLINFO_LOCATION This->adapter->gl_info /* Context activation is done by the caller. */ static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *context) { IWineD3DDeviceImpl *This = context; + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry); ENTER_GL(); @@ -1152,7 +1148,6 @@ static void atifs_free(IWineD3DDevice *iface) { HeapFree(GetProcessHeap(), 0, priv); This->fragment_priv = NULL; } -#undef GLINFO_LOCATION static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup) { diff --git a/dll/directx/wine/wined3d/basetexture.c b/dll/directx/wine/wined3d/basetexture.c index f3c3fe74e1b..deab4fb2362 100644 --- a/dll/directx/wine/wined3d/basetexture.c +++ b/dll/directx/wine/wined3d/basetexture.c @@ -27,9 +27,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture); -HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, - WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) +HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count, + WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage, + const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, + const struct wined3d_parent_ops *parent_ops) { HRESULT hr; @@ -41,7 +42,17 @@ HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DR return hr; } - texture->baseTexture.levels = levels; + texture->baseTexture.sub_resources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + level_count * layer_count * sizeof(*texture->baseTexture.sub_resources)); + if (!texture->baseTexture.sub_resources) + { + ERR("Failed to allocate sub-resource array.\n"); + resource_cleanup((IWineD3DResource *)texture); + return E_OUTOFMEMORY; + } + + texture->baseTexture.layer_count = layer_count; + texture->baseTexture.level_count = level_count; texture->baseTexture.filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; texture->baseTexture.LOD = 0; texture->baseTexture.texture_rgb.dirty = TRUE; @@ -66,9 +77,27 @@ HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DR void basetexture_cleanup(IWineD3DBaseTexture *iface) { basetexture_unload(iface); + HeapFree(GetProcessHeap(), 0, ((IWineD3DBaseTextureImpl *)iface)->baseTexture.sub_resources); resource_cleanup((IWineD3DResource *)iface); } +IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, UINT layer, UINT level) +{ + if (layer >= texture->baseTexture.layer_count) + { + WARN("layer %u >= layer_count %u.\n", layer, texture->baseTexture.layer_count); + return NULL; + } + + if (level >= texture->baseTexture.level_count) + { + WARN("level %u >= level_count %u.\n", level, texture->baseTexture.level_count); + return NULL; + } + + return texture->baseTexture.sub_resources[layer * texture->baseTexture.level_count + level]; +} + /* A GL context is provided by the caller */ static void gltexture_delete(struct gl_texture *tex) { @@ -86,7 +115,7 @@ void basetexture_unload(IWineD3DBaseTexture *iface) if (This->baseTexture.texture_rgb.name || This->baseTexture.texture_srgb.name) { - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } if(This->baseTexture.texture_rgb.name) { @@ -115,8 +144,8 @@ DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew) return 0; } - if(LODNew >= This->baseTexture.levels) - LODNew = This->baseTexture.levels - 1; + if (LODNew >= This->baseTexture.level_count) + LODNew = This->baseTexture.level_count - 1; if(This->baseTexture.LOD != LODNew) { This->baseTexture.LOD = LODNew; @@ -145,8 +174,8 @@ DWORD basetexture_get_lod(IWineD3DBaseTexture *iface) DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; - TRACE("(%p) : returning %d\n", This, This->baseTexture.levels); - return This->baseTexture.levels; + TRACE("iface %p, returning %u.\n", iface, This->baseTexture.level_count); + return This->baseTexture.level_count; } HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) @@ -164,7 +193,7 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT * Or should we delay the applying until the texture is used for drawing? For now, apply * immediately. */ - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); glBindTexture(textureDimensions, This->baseTexture.texture_rgb.name); @@ -270,9 +299,7 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0; gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1; gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = 0; - gl_tex->states[WINED3DTEXSTA_ELEMENTINDEX] = 0; - gl_tex->states[WINED3DTEXSTA_DMAPOFFSET] = 0; - gl_tex->states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP; + gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE; IWineD3DBaseTexture_SetDirty(iface, TRUE); isNewTexture = TRUE; @@ -301,10 +328,11 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac * relying on the partial GL_ARB_texture_non_power_of_two emulation with texture rectangles * (ie, do not care for cond_np2 here, just look for GL_TEXTURE_RECTANGLE_ARB) */ - if(textureDimensions != GL_TEXTURE_RECTANGLE_ARB) { - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); - glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); - checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)"); + if (textureDimensions != GL_TEXTURE_RECTANGLE_ARB) + { + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", This->baseTexture.level_count - 1); + glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count - 1); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count)"); } if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) { /* Cubemaps are always set to clamp, regardless of the sampler state. */ @@ -444,17 +472,18 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue); checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ..."); - if(!cond_np2) { - if(gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) { + if (!cond_np2) + { + if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) glValue = This->baseTexture.LOD; - } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) { - glValue = This->baseTexture.levels - 1; - } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) { + else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.level_count) + glValue = This->baseTexture.level_count - 1; + else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) /* baseTexture.LOD is already clamped in the setter */ glValue = This->baseTexture.LOD; - } else { + else glValue = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL]; - } + /* Note that D3DSAMP_MAXMIPLEVEL specifies the biggest mipmap(default 0), while * GL_TEXTURE_MAX_LEVEL specifies the smallest mimap used(default 1000). * So D3DSAMP_MAXMIPLEVEL is the same as GL_TEXTURE_BASE_LEVEL. @@ -488,4 +517,22 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, } gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso; } + + if (!(This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW) + != !gl_tex->states[WINED3DTEXSTA_SHADOW]) + { + if (This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW) + { + glTexParameteri(textureDimensions, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); + glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)"); + gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE; + } + else + { + glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)"); + gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE; + } + } } diff --git a/dll/directx/wine/wined3d/buffer.c b/dll/directx/wine/wined3d/buffer.c index e22d311beb9..daece20c33d 100644 --- a/dll/directx/wine/wined3d/buffer.c +++ b/dll/directx/wine/wined3d/buffer.c @@ -29,8 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION This->resource.device->adapter->gl_info - #define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ #define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ @@ -97,11 +95,29 @@ static inline BOOL buffer_is_fully_dirty(struct wined3d_buffer *This) return FALSE; } +/* Context activation is done by the caller */ +static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) +{ + if(!This->buffer_object) return; + + ENTER_GL(); + GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); + checkGLcall("glDeleteBuffersARB"); + LEAVE_GL(); + This->buffer_object = 0; + + if(This->query) + { + wined3d_event_query_destroy(This->query); + This->query = NULL; + } + This->flags &= ~WINED3D_BUFFER_APPLESYNC; +} + /* Context activation is done by the caller. */ -static void buffer_create_buffer_object(struct wined3d_buffer *This) +static void buffer_create_buffer_object(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) { GLenum error, gl_usage; - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n", This, debug_d3dusage(This->resource.usage)); @@ -157,6 +173,10 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); This->flags |= WINED3D_BUFFER_FLUSH; + + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); + This->flags |= WINED3D_BUFFER_APPLESYNC; } /* No setup is needed here for GL_ARB_map_buffer_range */ } @@ -203,13 +223,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) fail: /* Clean up all vbo init, but continue because we can work without a vbo :-) */ ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n"); - if (This->buffer_object) - { - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); - LEAVE_GL(); - } - This->buffer_object = 0; + delete_gl_buffer(This, gl_info); buffer_clear_dirty_areas(This); } @@ -258,12 +272,13 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, attrib_size = attrib->format_desc->component_count * attrib->format_desc->component_size; for (i = 0; i < attrib_size; ++i) { - if (This->conversion_map[data + i] != conversion_type) + DWORD_PTR idx = (data + i) % This->stride; + if (This->conversion_map[idx] != conversion_type) { - TRACE("Byte %ld in vertex changed\n", i + data); - TRACE("It was type %d, is %d now\n", This->conversion_map[data + i], conversion_type); + TRACE("Byte %ld in vertex changed\n", idx); + TRACE("It was type %d, is %d now\n", This->conversion_map[idx], conversion_type); ret = TRUE; - This->conversion_map[data + i] = conversion_type; + This->conversion_map[idx] = conversion_type; } } @@ -534,7 +549,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) } /* Context activation is done by the caller. */ -static void buffer_check_buffer_object_size(struct wined3d_buffer *This) +static void buffer_check_buffer_object_size(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) { UINT size = This->conversion_stride ? This->conversion_stride * (This->resource.size / This->stride) : This->resource.size; @@ -550,7 +565,7 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This) /* Rescue the data before resizing the buffer object if we do not have our backup copy */ if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(This); + buffer_get_sysmem(This, gl_info); } ENTER_GL(); @@ -595,7 +610,7 @@ static inline void fixup_transformed_pos(float *p) } /* Context activation is done by the caller. */ -const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) +const BYTE *buffer_get_memory(IWineD3DBuffer *iface, const struct wined3d_gl_info *gl_info, GLuint *buffer_object) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; @@ -604,19 +619,19 @@ const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer { if (This->flags & WINED3D_BUFFER_CREATEBO) { - buffer_create_buffer_object(This); + buffer_create_buffer_object(This, gl_info); This->flags &= ~WINED3D_BUFFER_CREATEBO; if (This->buffer_object) { *buffer_object = This->buffer_object; - return (const BYTE *)offset; + return NULL; } } - return This->resource.allocatedMemory + offset; + return This->resource.allocatedMemory; } else { - return (const BYTE *)offset; + return NULL; } } @@ -655,7 +670,7 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) } /* Context activation is done by the caller. */ -BYTE *buffer_get_sysmem(struct wined3d_buffer *This) +BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) { /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */ if(This->resource.allocatedMemory) return This->resource.allocatedMemory; @@ -682,20 +697,16 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context; - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); /* Download the buffer, but don't permanently enable double buffering */ if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(This); + buffer_get_sysmem(This, context->gl_info); This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; } - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - This->buffer_object = 0; + delete_gl_buffer(This, context->gl_info); This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */ buffer_clear_dirty_areas(This); @@ -766,26 +777,171 @@ static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) return resource_get_priority((IWineD3DResource *)iface); } +/* The caller provides a context and binds the buffer */ +static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const struct wined3d_gl_info *gl_info) +{ + enum wined3d_event_query_result ret; + + /* No fencing needs to be done if the app promises not to overwrite + * existing data */ + if(flags & WINED3DLOCK_NOOVERWRITE) return; + if(flags & WINED3DLOCK_DISCARD) + { + ENTER_GL(); + GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage)); + checkGLcall("glBufferDataARB\n"); + LEAVE_GL(); + return; + } + + if(!This->query) + { + TRACE("Creating event query for buffer %p\n", This); + + if (!wined3d_event_query_supported(gl_info)) + { + FIXME("Event queries not supported, dropping async buffer locks.\n"); + goto drop_query; + } + + This->query = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->query)); + if (!This->query) + { + ERR("Failed to allocate event query memory, dropping async buffer locks.\n"); + goto drop_query; + } + + /* Since we don't know about old draws a glFinish is needed once */ + wglFinish(); + return; + } + TRACE("Synchronizing buffer %p\n", This); + ret = wined3d_event_query_finish(This->query, This->resource.device); + switch(ret) + { + case WINED3D_EVENT_QUERY_NOT_STARTED: + case WINED3D_EVENT_QUERY_OK: + /* All done */ + return; + + case WINED3D_EVENT_QUERY_WRONG_THREAD: + WARN("Cannot synchronize buffer lock due to a thread conflict\n"); + goto drop_query; + + default: + ERR("wined3d_event_query_finish returned %u, dropping async buffer locks\n", ret); + goto drop_query; + } + +drop_query: + if(This->query) + { + wined3d_event_query_destroy(This->query); + This->query = NULL; + } + + wglFinish(); + ENTER_GL(); + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); + LEAVE_GL(); + This->flags &= ~WINED3D_BUFFER_APPLESYNC; +} + +/* The caller provides a GL context */ +static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) +{ + BYTE *map; + UINT start = 0, len = 0; + + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + checkGLcall("glBindBufferARB"); + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield mapflags; + mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; + if (flags & WINED3D_BUFFER_DISCARD) + { + mapflags |= GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; + } + else if (flags & WINED3D_BUFFER_NOSYNC) + { + mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; + } + map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, + This->resource.size, mapflags)); + checkGLcall("glMapBufferRange"); + } + else + { + if (This->flags & WINED3D_BUFFER_APPLESYNC) + { + DWORD syncflags = 0; + if (flags & WINED3D_BUFFER_DISCARD) syncflags |= WINED3DLOCK_DISCARD; + if (flags & WINED3D_BUFFER_NOSYNC) syncflags |= WINED3DLOCK_NOOVERWRITE; + LEAVE_GL(); + buffer_sync_apple(This, syncflags, gl_info); + ENTER_GL(); + } + map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB)); + checkGLcall("glMapBufferARB"); + } + if (!map) + { + LEAVE_GL(); + ERR("Failed to map opengl buffer\n"); + return; + } + + while(This->modified_areas) + { + This->modified_areas--; + start = This->maps[This->modified_areas].offset; + len = This->maps[This->modified_areas].size; + + memcpy(map + start, This->resource.allocatedMemory + start, len); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRange"); + } + else if (This->flags & WINED3D_BUFFER_FLUSH) + { + GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRangeAPPLE"); + } + } + GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + checkGLcall("glUnmapBufferARB"); + LEAVE_GL(); +} + static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; IWineD3DDeviceImpl *device = This->resource.device; UINT start = 0, end = 0, len = 0, vertices; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; BOOL decl_changed = FALSE; unsigned int i, j; BYTE *data; + DWORD flags = This->flags & (WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD); TRACE("iface %p\n", iface); + This->flags &= ~(WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD); - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); + gl_info = context->gl_info; if (!This->buffer_object) { /* TODO: Make converting independent from VBOs */ if (This->flags & WINED3D_BUFFER_CREATEBO) { - buffer_create_buffer_object(This); + buffer_create_buffer_object(This, gl_info); This->flags &= ~WINED3D_BUFFER_CREATEBO; } else @@ -836,7 +992,20 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC); goto end; } - buffer_check_buffer_object_size(This); + buffer_check_buffer_object_size(This, gl_info); + + /* The declaration changed, reload the whole buffer */ + WARN("Reloading buffer because of decl change\n"); + buffer_clear_dirty_areas(This); + if(!buffer_add_dirty_area(This, 0, 0)) + { + ERR("buffer_add_dirty_area failed, this is not expected\n"); + return; + } + /* Avoid unfenced updates, we might overwrite more areas of the buffer than the application + * cleared for unsynchronized updates + */ + flags = 0; } else { @@ -864,18 +1033,6 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) } } - if (decl_changed) - { - /* The declaration changed, reload the whole buffer */ - WARN("Reloading buffer because of decl change\n"); - buffer_clear_dirty_areas(This); - if(!buffer_add_dirty_area(This, 0, 0)) - { - ERR("buffer_add_dirty_area failed, this is not expected\n"); - return; - } - } - if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) { IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); @@ -896,18 +1053,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) return; } - ENTER_GL(); - GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBufferARB"); - while(This->modified_areas) - { - This->modified_areas--; - start = This->maps[This->modified_areas].offset; - len = This->maps[This->modified_areas].size; - GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, len, This->resource.allocatedMemory + start)); - checkGLcall("glBufferSubDataARB"); - } - LEAVE_GL(); + buffer_direct_upload(This, context->gl_info, flags); context_release(context); return; @@ -915,7 +1061,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - buffer_get_sysmem(This); + buffer_get_sysmem(This, gl_info); } /* Now for each vertex in the buffer that needs conversion */ @@ -1033,7 +1179,7 @@ static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *ifac /* IWineD3DBuffer methods */ -static DWORD buffer_sanitize_flags(DWORD flags) +static DWORD buffer_sanitize_flags(struct wined3d_buffer *buffer, DWORD flags) { /* Not all flags make sense together, but Windows never returns an error. Catch the * cases that could cause issues */ @@ -1055,6 +1201,11 @@ static DWORD buffer_sanitize_flags(DWORD flags) WARN("WINED3DLOCK_DISCARD and WINED3DLOCK_NOOVERWRITE used together, ignoring\n"); return 0; } + else if (flags & (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE) && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC)) + { + WARN("DISCARD or NOOVERWRITE lock on non-dynamic buffer, ignoring\n"); + return 0; + } return flags; } @@ -1082,10 +1233,11 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; LONG count; + BOOL dirty = buffer_is_dirty(This); TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags); - flags = buffer_sanitize_flags(flags); + flags = buffer_sanitize_flags(This, flags); if (!(flags & WINED3DLOCK_READONLY)) { if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY; @@ -1093,36 +1245,81 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, count = InterlockedIncrement(&This->lock_count); - if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object) + if (This->buffer_object) { - if(count == 1) + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) { - IWineD3DDeviceImpl *device = This->resource.device; - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - - if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + if(count == 1) { - IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); + IWineD3DDeviceImpl *device = This->resource.device; + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); + } + + context = context_acquire(device, NULL); + gl_info = context->gl_info; + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield mapflags = buffer_gl_map_flags(flags); + This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, + This->resource.size, mapflags)); + checkGLcall("glMapBufferRange"); + } + else + { + if(This->flags & WINED3D_BUFFER_APPLESYNC) + { + LEAVE_GL(); + buffer_sync_apple(This, flags, gl_info); + ENTER_GL(); + } + This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB)); + checkGLcall("glMapBufferARB"); + } + LEAVE_GL(); + + if (((DWORD_PTR) This->resource.allocatedMemory) & (RESOURCE_ALIGNMENT - 1)) + { + WARN("Pointer %p is not %u byte aligned, falling back to double buffered operation\n", + This->resource.allocatedMemory, RESOURCE_ALIGNMENT); + + ENTER_GL(); + GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + checkGLcall("glUnmapBufferARB"); + LEAVE_GL(); + This->resource.allocatedMemory = NULL; + + buffer_get_sysmem(This, gl_info); + TRACE("New pointer is %p\n", This->resource.allocatedMemory); + } + context_release(context); + } + } + else + { + if (dirty) + { + if (This->flags & WINED3D_BUFFER_NOSYNC && !(flags & WINED3DLOCK_NOOVERWRITE)) + { + This->flags &= ~WINED3D_BUFFER_NOSYNC; + } + } + else if(flags & WINED3DLOCK_NOOVERWRITE) + { + This->flags |= WINED3D_BUFFER_NOSYNC; } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); - gl_info = context->gl_info; - ENTER_GL(); - GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + if (flags & WINED3DLOCK_DISCARD) { - GLbitfield mapflags = buffer_gl_map_flags(flags); - This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, - This->resource.size, mapflags)); + This->flags |= WINED3D_BUFFER_DISCARD; } - else - { - This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB)); - } - LEAVE_GL(); - context_release(context); } } @@ -1169,7 +1366,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER); } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; ENTER_GL(); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); @@ -1251,7 +1448,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info); HRESULT hr; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; BOOL dynamic_buffer_ok; @@ -1276,7 +1473,8 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format_desc->format), buffer->resource.allocatedMemory, buffer); - dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; + /* GL_ARB_map_buffer_range is disabled for now due to numerous bugs and no gains */ + dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE]; /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + * drawStridedFast (half-life 2 and others). diff --git a/dll/directx/wine/wined3d/context.c b/dll/directx/wine/wined3d/context.c index 08789855812..5304af2f408 100644 --- a/dll/directx/wine/wined3d/context.c +++ b/dll/directx/wine/wined3d/context.c @@ -28,8 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - static DWORD wined3d_context_tls_idx; /* FBO helper functions */ @@ -84,19 +82,19 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb } /* GL locking is done by the caller */ -static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info) +static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info, GLenum target) { unsigned int i; for (i = 0; i < gl_info->limits.buffers; ++i) { - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); } - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glFramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); - gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glFramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); checkGLcall("glFramebufferTexture2D()"); } @@ -106,7 +104,7 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo) const struct wined3d_gl_info *gl_info = context->gl_info; context_bind_fbo(context, GL_FRAMEBUFFER, fbo); - context_clean_fbo_attachments(gl_info); + context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER); context_bind_fbo(context, GL_FRAMEBUFFER, NULL); gl_info->fbo_ops.glDeleteFramebuffers(1, fbo); @@ -114,17 +112,18 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo) } /* GL locking is done by the caller */ -static void context_apply_attachment_filter_states(IWineD3DSurface *surface) +static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface) { - const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; - IWineD3DDeviceImpl *device = surface_impl->resource.device; IWineD3DBaseTextureImpl *texture_impl; - BOOL update_minfilter = FALSE; - BOOL update_magfilter = FALSE; /* Update base texture states array */ - if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&texture_impl))) { + IWineD3DDeviceImpl *device = surface->resource.device; + BOOL update_minfilter = FALSE; + BOOL update_magfilter = FALSE; + if (texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] != WINED3DTEXF_POINT || texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] != WINED3DTEXF_NONE) { @@ -146,82 +145,85 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface) } IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl); - } - if (update_minfilter || update_magfilter) - { - GLenum target, bind_target; - GLint old_binding; - - target = surface_impl->texture_target; - if (target == GL_TEXTURE_2D) + if (update_minfilter || update_magfilter) { - bind_target = GL_TEXTURE_2D; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); - } else if (target == GL_TEXTURE_RECTANGLE_ARB) { - bind_target = GL_TEXTURE_RECTANGLE_ARB; - glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); - } else { - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding); + GLenum target, bind_target; + GLint old_binding; + + target = surface->texture_target; + if (target == GL_TEXTURE_2D) + { + bind_target = GL_TEXTURE_2D; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); + } + else if (target == GL_TEXTURE_RECTANGLE_ARB) + { + bind_target = GL_TEXTURE_RECTANGLE_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); + } + else + { + bind_target = GL_TEXTURE_CUBE_MAP_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding); + } + + glBindTexture(bind_target, surface->texture_name); + if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindTexture(bind_target, old_binding); } - glBindTexture(bind_target, surface_impl->texture_name); - if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindTexture(bind_target, old_binding); + checkGLcall("apply_attachment_filter_states()"); } - - checkGLcall("apply_attachment_filter_states()"); } /* GL locking is done by the caller */ void context_attach_depth_stencil_fbo(struct wined3d_context *context, - GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) + GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer) { - IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Attach depth stencil %p\n", depth_stencil); if (depth_stencil) { - DWORD format_flags = depth_stencil_impl->resource.format_desc->Flags; + DWORD format_flags = depth_stencil->resource.format_desc->Flags; - if (use_render_buffer && depth_stencil_impl->current_renderbuffer) + if (use_render_buffer && depth_stencil->current_renderbuffer) { if (format_flags & WINED3DFMT_FLAG_DEPTH) { gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id); + GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id); checkGLcall("glFramebufferRenderbuffer()"); } if (format_flags & WINED3DFMT_FLAG_STENCIL) { gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id); + GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id); checkGLcall("glFramebufferRenderbuffer()"); } } else { - surface_prepare_texture(depth_stencil_impl, FALSE); + surface_prepare_texture(depth_stencil, gl_info, FALSE); context_apply_attachment_filter_states(depth_stencil); if (format_flags & WINED3DFMT_FLAG_DEPTH) { gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, - depth_stencil_impl->texture_target, depth_stencil_impl->texture_name, - depth_stencil_impl->texture_level); + depth_stencil->texture_target, depth_stencil->texture_name, + depth_stencil->texture_level); checkGLcall("glFramebufferTexture2D()"); } if (format_flags & WINED3DFMT_FLAG_STENCIL) { gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, - depth_stencil_impl->texture_target, depth_stencil_impl->texture_name, - depth_stencil_impl->texture_level); + depth_stencil->texture_target, depth_stencil->texture_name, + depth_stencil->texture_level); checkGLcall("glFramebufferTexture2D()"); } } @@ -249,21 +251,20 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context, } /* GL locking is done by the caller */ -void context_attach_surface_fbo(const struct wined3d_context *context, - GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) +static void context_attach_surface_fbo(const struct wined3d_context *context, + GLenum fbo_target, DWORD idx, IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface; const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Attach surface %p to %u\n", surface, idx); if (surface) { - surface_prepare_texture(surface_impl, FALSE); + surface_prepare_texture(surface, gl_info, FALSE); context_apply_attachment_filter_states(surface); - gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface_impl->texture_target, - surface_impl->texture_name, surface_impl->texture_level); + gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface->texture_target, + surface->texture_name, surface->texture_level); checkGLcall("glFramebufferTexture2D()"); } else @@ -274,12 +275,12 @@ void context_attach_surface_fbo(const struct wined3d_context *context, } /* GL locking is done by the caller */ -static void context_check_fbo_status(struct wined3d_context *context) +static void context_check_fbo_status(struct wined3d_context *context, GLenum target) { const struct wined3d_gl_info *gl_info = context->gl_info; GLenum status; - status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + status = gl_info->fbo_ops.glCheckFramebufferStatus(target); if (status == GL_FRAMEBUFFER_COMPLETE) { TRACE("FBO complete\n"); @@ -297,7 +298,7 @@ static void context_check_fbo_status(struct wined3d_context *context) /* Dump the FBO attachments */ for (i = 0; i < gl_info->limits.buffers; ++i) { - attachment = (IWineD3DSurfaceImpl *)context->current_fbo->render_targets[i]; + attachment = context->current_fbo->render_targets[i]; if (attachment) { FIXME("\tColor attachment %d: (%p) %s %ux%u\n", @@ -305,7 +306,7 @@ static void context_check_fbo_status(struct wined3d_context *context) attachment->pow2Width, attachment->pow2Height); } } - attachment = (IWineD3DSurfaceImpl *)context->current_fbo->depth_stencil; + attachment = context->current_fbo->depth_stencil; if (attachment) { FIXME("\tDepth attachment: (%p) %s %ux%u\n", @@ -315,16 +316,16 @@ static void context_check_fbo_status(struct wined3d_context *context) } } -static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context) +static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry; entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets)); - memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = device->stencilBufferTarget; + memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); + entry->depth_stencil = depth_stencil; entry->attached = FALSE; entry->id = 0; @@ -332,16 +333,17 @@ static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *contex } /* GL locking is done by the caller */ -static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil, + struct fbo_entry *entry) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; - context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); - context_clean_fbo_attachments(gl_info); + context_bind_fbo(context, target, &entry->id); + context_clean_fbo_attachments(gl_info, target); - memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = device->stencilBufferTarget; + memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); + entry->depth_stencil = depth_stencil; entry->attached = FALSE; } @@ -361,17 +363,17 @@ static void context_destroy_fbo_entry(struct wined3d_context *context, struct fb /* GL locking is done by the caller */ -static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) +static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry; LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry) { if (!memcmp(entry->render_targets, - device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)) - && entry->depth_stencil == device->stencilBufferTarget) + render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)) + && entry->depth_stencil == depth_stencil) { list_remove(&entry->entry); list_add_head(&context->fbo_list, &entry->entry); @@ -381,14 +383,14 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES) { - entry = context_create_fbo_entry(context); + entry = context_create_fbo_entry(context, render_targets, depth_stencil); list_add_head(&context->fbo_list, &entry->entry); ++context->fbo_entry_count; } else { entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry); - context_reuse_fbo_entry(context, entry); + context_reuse_fbo_entry(context, target, render_targets, depth_stencil, entry); list_remove(&entry->entry); list_add_head(&context->fbo_list, &entry->entry); } @@ -397,32 +399,28 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) } /* GL locking is done by the caller */ -static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; - context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id); + context_bind_fbo(context, target, &entry->id); if (!entry->attached) { /* Apply render targets */ for (i = 0; i < gl_info->limits.buffers; ++i) { - IWineD3DSurface *render_target = device->render_targets[i]; - context_attach_surface_fbo(context, GL_FRAMEBUFFER, i, render_target); + context_attach_surface_fbo(context, target, i, entry->render_targets[i]); } /* Apply depth targets */ - if (device->stencilBufferTarget) + if (entry->depth_stencil) { - unsigned int w = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Width; - unsigned int h = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Height; - - surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h); + surface_set_compatible_renderbuffer(entry->depth_stencil, + entry->render_targets[0]->pow2Width, entry->render_targets[0]->pow2Height); } - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, device->stencilBufferTarget, TRUE); + context_attach_depth_stencil_fbo(context, target, entry->depth_stencil, TRUE); entry->attached = TRUE; } @@ -430,24 +428,17 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ { for (i = 0; i < gl_info->limits.buffers; ++i) { - if (device->render_targets[i]) - context_apply_attachment_filter_states(device->render_targets[i]); + if (entry->render_targets[i]) + context_apply_attachment_filter_states(entry->render_targets[i]); } - if (device->stencilBufferTarget) - context_apply_attachment_filter_states(device->stencilBufferTarget); - } - - for (i = 0; i < gl_info->limits.buffers; ++i) - { - if (device->render_targets[i]) - device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; - else - device->draw_buffers[i] = GL_NONE; + if (entry->depth_stencil) + context_apply_attachment_filter_states(entry->depth_stencil); } } /* GL locking is done by the caller */ -static void context_apply_fbo_state(struct wined3d_context *context) +static void context_apply_fbo_state(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil) { struct fbo_entry *entry, *entry2; @@ -456,16 +447,39 @@ static void context_apply_fbo_state(struct wined3d_context *context) context_destroy_fbo_entry(context, entry); } - if (context->render_offscreen) + if (context->rebind_fbo) { - context->current_fbo = context_find_fbo_entry(context); - context_apply_fbo_entry(context, context->current_fbo); - } else { - context->current_fbo = NULL; context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + context->rebind_fbo = FALSE; } - context_check_fbo_status(context); + if (render_targets) + { + context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil); + context_apply_fbo_entry(context, target, context->current_fbo); + } + else + { + context->current_fbo = NULL; + context_bind_fbo(context, target, NULL); + } + + context_check_fbo_status(context, target); +} + +/* GL locking is done by the caller */ +void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) +{ + if (surface_is_offscreen(render_target)) + { + context->blit_targets[0] = render_target; + context_apply_fbo_state(context, target, context->blit_targets, depth_stencil); + } + else + { + context_apply_fbo_state(context, target, NULL, NULL); + } } /* Context activation is done by the caller. */ @@ -614,13 +628,13 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource const struct wined3d_gl_info *gl_info = context->gl_info; struct fbo_entry *entry, *entry2; - if (context->current_rt == (IWineD3DSurface *)resource) context->current_rt = NULL; + if (context->current_rt == (IWineD3DSurfaceImpl *)resource) context->current_rt = NULL; LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) { UINT j; - if (entry->depth_stencil == (IWineD3DSurface *)resource) + if (entry->depth_stencil == (IWineD3DSurfaceImpl *)resource) { list_remove(&entry->entry); list_add_head(&context->fbo_destroy_list, &entry->entry); @@ -629,7 +643,7 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource for (j = 0; j < gl_info->limits.buffers; ++j) { - if (entry->render_targets[j] == (IWineD3DSurface *)resource) + if (entry->render_targets[j] == (IWineD3DSurfaceImpl *)resource) { list_remove(&entry->entry); list_add_head(&context->fbo_destroy_list, &entry->entry); @@ -647,6 +661,115 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource } } +void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct fbo_entry *entry = context->current_fbo; + unsigned int i; + + if (!entry || context->rebind_fbo) return; + + for (i = 0; i < gl_info->limits.buffers; ++i) + { + if (surface == entry->render_targets[i]) + { + TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i); + context->rebind_fbo = TRUE; + return; + } + } + + if (surface == entry->depth_stencil) + { + TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface); + context->rebind_fbo = TRUE; + } +} + +static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format) +{ + int current = GetPixelFormat(dc); + + if (current == format) return TRUE; + + if (!current) + { + if (!SetPixelFormat(dc, format, NULL)) + { + ERR("Failed to set pixel format %d on device context %p, last error %#x.\n", + format, dc, GetLastError()); + return FALSE; + } + return TRUE; + } + + /* By default WGL doesn't allow pixel format adjustments but we need it + * here. For this reason there's a Wine specific wglSetPixelFormat() + * which allows us to set the pixel format multiple times. Only use it + * when really needed. */ + if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) + { + if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format, NULL))) + { + ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n", + format, dc); + return FALSE; + } + return TRUE; + } + + /* OpenGL doesn't allow pixel format adjustments. Print an error and + * continue using the old format. There's a big chance that the old + * format works although with a performance hit and perhaps rendering + * errors. */ + ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n", + format, dc, current); + return TRUE; +} + +static void context_update_window(struct wined3d_context *context) +{ + TRACE("Updating context %p window from %p to %p.\n", + context, context->win_handle, context->swapchain->win_handle); + + if (context->valid) + { + if (!ReleaseDC(context->win_handle, context->hdc)) + { + ERR("Failed to release device context %p, last error %#x.\n", + context->hdc, GetLastError()); + } + } + else context->valid = 1; + + context->win_handle = context->swapchain->win_handle; + + if (!(context->hdc = GetDC(context->win_handle))) + { + ERR("Failed to get a device context for window %p.\n", context->win_handle); + goto err; + } + + if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format)) + { + ERR("Failed to set pixel format %d on device context %p.\n", + context->pixel_format, context->hdc); + goto err; + } + + if (!pwglMakeCurrent(context->hdc, context->glCtx)) + { + ERR("Failed to make GL context %p current on device context %p, last error %#x.\n", + context->glCtx, context->hdc, GetLastError()); + goto err; + } + + return; + +err: + context->valid = 0; +} + static void context_validate(struct wined3d_context *context) { HWND wnd = WindowFromDC(context->hdc); @@ -657,6 +780,9 @@ static void context_validate(struct wined3d_context *context) context->hdc, wnd, context->win_handle); context->valid = 0; } + + if (context->win_handle != context->swapchain->win_handle) + context_update_window(context); } static void context_destroy_gl_resources(struct wined3d_context *context) @@ -713,11 +839,6 @@ static void context_destroy_gl_resources(struct wined3d_context *context) if (context->valid) { - if (context->src_fbo) - { - TRACE("Destroy src FBO %d\n", context->src_fbo); - context_destroy_fbo(context, &context->src_fbo); - } if (context->dst_fbo) { TRACE("Destroy dst FBO %d\n", context->dst_fbo); @@ -772,15 +893,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context) ERR("Failed to disable GL context.\n"); } - if (context->pbuffer) - { - GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc)); - GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer)); - } - else - { - ReleaseDC(context->win_handle, context->hdc); - } + ReleaseDC(context->win_handle, context->hdc); if (!pwglDeleteContext(context->glCtx)) { @@ -928,68 +1041,10 @@ static void Context_MarkStateDirty(struct wined3d_context *context, DWORD state, context->isStateDirty[idx] |= (1 << shift); } -/***************************************************************************** - * AddContextToArray - * - * Adds a context to the context array. Helper function for context_create(). - * - * This method is not called in performance-critical code paths, only when a - * new render target or swapchain is created. Thus performance is not an issue - * here. - * - * Params: - * This: Device to add the context for - * hdc: device context - * glCtx: WGL context to add - * pbuffer: optional pbuffer used with this context - * - *****************************************************************************/ -static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This, - HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer) -{ - struct wined3d_context **oldArray = This->contexts; - DWORD state; - - This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1)); - if(This->contexts == NULL) { - ERR("Unable to grow the context array\n"); - This->contexts = oldArray; - return NULL; - } - if(oldArray) { - memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts); - } - - This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**This->contexts)); - if(This->contexts[This->numContexts] == NULL) { - ERR("Unable to allocate a new context\n"); - HeapFree(GetProcessHeap(), 0, This->contexts); - This->contexts = oldArray; - return NULL; - } - - This->contexts[This->numContexts]->hdc = hdc; - This->contexts[This->numContexts]->glCtx = glCtx; - This->contexts[This->numContexts]->pbuffer = pbuffer; - This->contexts[This->numContexts]->win_handle = win_handle; - HeapFree(GetProcessHeap(), 0, oldArray); - - /* Mark all states dirty to force a proper initialization of the states on the first use of the context - */ - for(state = 0; state <= STATE_HIGHEST; state++) { - if (This->StateTable[state].representative) - Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable); - } - - This->numContexts++; - TRACE("Created context %p\n", This->contexts[This->numContexts - 1]); - return This->contexts[This->numContexts - 1]; -} - /* This function takes care of WineD3D pixel format selection. */ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, - const struct GlPixelFormatDesc *color_format_desc, const struct GlPixelFormatDesc *ds_format_desc, - BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible) + const struct wined3d_format_desc *color_format_desc, const struct wined3d_format_desc *ds_format_desc, + BOOL auxBuffers, int numSamples, BOOL findCompatible) { int iPixelFormat=0; unsigned int matchtry; @@ -1019,9 +1074,9 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, int i = 0; int nCfgs = This->adapter->nCfgs; - TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, pbuffer=%d, findCompatible=%d\n", + TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, findCompatible=%d\n", debug_d3dformat(color_format_desc->format), debug_d3dformat(ds_format_desc->format), - auxBuffers, numSamples, pbuffer, findCompatible); + auxBuffers, numSamples, findCompatible); if (!getColorBits(color_format_desc, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) { @@ -1030,23 +1085,6 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, return 0; } - /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. - * You are able to add a depth + stencil surface at a later stage when you need it. - * In order to support this properly in WineD3D we need the ability to recreate the opengl context and - * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new - * context, need torecreate shaders, textures and other resources. - * - * The context manager already takes care of the state problem and for the other tasks code from Reset - * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. - * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the - * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this - * issue needs to be fixed. */ - if (ds_format_desc->format != WINED3DFMT_D24_UNORM_S8_UINT) - { - FIXME("Add OpenGL context recreation support to SetDepthStencilSurface\n"); - ds_format_desc = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, &This->adapter->gl_info); - } - getDepthStencilBits(ds_format_desc, &depthBits, &stencilBits); for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])) && !iPixelFormat; matchtry++) { @@ -1059,18 +1097,14 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, if(cfg->iPixelType != WGL_TYPE_RGBA_ARB) continue; - /* In window mode (!pbuffer) we need a window drawable format and double buffering. */ - if(!pbuffer && !(cfg->windowDrawable && cfg->doubleBuffer)) + /* In window mode we need a window drawable format and double buffering. */ + if(!(cfg->windowDrawable && cfg->doubleBuffer)) continue; /* We like to have aux buffers in backbuffer mode */ if(auxBuffers && !cfg->auxBuffers && matches[matchtry].require_aux) continue; - /* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */ - if(pbuffer && (!cfg->pbufferDrawable || cfg->doubleBuffer)) - continue; - if(matches[matchtry].exact_color) { if(cfg->redSize != redBits) continue; @@ -1167,227 +1201,174 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, /***************************************************************************** * context_create * - * Creates a new context for a window, or a pbuffer context. + * Creates a new context. * * * Params: * This: Device to activate the context for * target: Surface this context will render to * win_handle: handle to the window which we are drawing to - * create_pbuffer: tells whether to create a pbuffer or not * pPresentParameters: contains the pixelformats to use for onscreen rendering * *****************************************************************************/ -struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, - HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) +struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target, + const struct wined3d_format_desc *ds_format_desc) { - const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; - struct wined3d_context *ret = NULL; - HPBUFFERARB pbuffer = NULL; + IWineD3DDeviceImpl *device = swapchain->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_format_desc *color_format_desc; + struct wined3d_context *ret; + PIXELFORMATDESCRIPTOR pfd; + BOOL auxBuffers = FALSE; + int numSamples = 0; + int pixel_format; unsigned int s; + DWORD state; HGLRC ctx; HDC hdc; - TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target); + TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle); - if(create_pbuffer) { - HDC hdc_parent = GetDC(win_handle); - int iPixelFormat = 0; + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); + if (!ret) + { + ERR("Failed to allocate context memory.\n"); + return NULL; + } - IWineD3DSurface *StencilSurface = This->stencilBufferTarget; - const struct GlPixelFormatDesc *ds_format_desc = StencilSurface - ? ((IWineD3DSurfaceImpl *)StencilSurface)->resource.format_desc - : getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info); + if (!(hdc = GetDC(swapchain->win_handle))) + { + ERR("Failed to retrieve a device context.\n"); + goto out; + } - /* Try to find a pixel format with pbuffer support. */ - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format_desc, - ds_format_desc, FALSE /* auxBuffers */, 0 /* numSamples */, TRUE /* PBUFFER */, - FALSE /* findCompatible */); - if(!iPixelFormat) { - TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); + color_format_desc = target->resource.format_desc; - /* For some reason we weren't able to find a format, try to find something instead of crashing. - * A reason for failure could have been wglChoosePixelFormatARB strictness. */ - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format_desc, - ds_format_desc, FALSE /* auxBuffer */, 0 /* numSamples */, TRUE /* PBUFFER */, - TRUE /* findCompatible */); - } + /* In case of ORM_BACKBUFFER, make sure to request an alpha component for + * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ + if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) + { + auxBuffers = TRUE; - /* This shouldn't happen as ChoosePixelFormat always returns something */ - if(!iPixelFormat) { - ERR("Unable to locate a pixel format for a pbuffer\n"); - ReleaseDC(win_handle, hdc_parent); - goto out; - } + if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM) + color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, gl_info); + else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) + color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); + } - TRACE("Creating a pBuffer drawable for the new context\n"); - pbuffer = GL_EXTCALL(wglCreatePbufferARB(hdc_parent, iPixelFormat, target->currentDesc.Width, target->currentDesc.Height, 0)); - if(!pbuffer) { - ERR("Cannot create a pbuffer\n"); - ReleaseDC(win_handle, hdc_parent); - goto out; - } + /* DirectDraw supports 8bit paletted render targets and these are used by + * old games like Starcraft and C&C. Most modern hardware doesn't support + * 8bit natively so we perform some form of 8bit -> 32bit conversion. The + * conversion (ab)uses the alpha component for storing the palette index. + * For this reason we require a format with 8bit alpha, so request + * A8R8G8B8. */ + if (color_format_desc->format == WINED3DFMT_P8_UINT) + color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); - /* In WGL a pbuffer is 'wrapped' inside a HDC to 'fool' wglMakeCurrent */ - hdc = GL_EXTCALL(wglGetPbufferDCARB(pbuffer)); - if(!hdc) { - ERR("Cannot get a HDC for pbuffer (%p)\n", pbuffer); - GL_EXTCALL(wglDestroyPbufferARB(pbuffer)); - ReleaseDC(win_handle, hdc_parent); - goto out; - } - ReleaseDC(win_handle, hdc_parent); - } else { - PIXELFORMATDESCRIPTOR pfd; - int iPixelFormat; - int res; - const struct GlPixelFormatDesc *color_format_desc = target->resource.format_desc; - const struct GlPixelFormatDesc *ds_format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, - &This->adapter->gl_info); - BOOL auxBuffers = FALSE; - int numSamples = 0; - - hdc = GetDC(win_handle); - if(hdc == NULL) { - ERR("Cannot retrieve a device context!\n"); - goto out; - } - - /* In case of ORM_BACKBUFFER, make sure to request an alpha component for X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ - if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { - auxBuffers = TRUE; - - if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM) - color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, &This->adapter->gl_info); - else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) - color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->adapter->gl_info); - } - - /* DirectDraw supports 8bit paletted render targets and these are used by old games like Starcraft and C&C. - * Most modern hardware doesn't support 8bit natively so we perform some form of 8bit -> 32bit conversion. - * The conversion (ab)uses the alpha component for storing the palette index. For this reason we require - * a format with 8bit alpha, so request A8R8G8B8. */ - if (color_format_desc->format == WINED3DFMT_P8_UINT) - color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, &This->adapter->gl_info); - - /* Retrieve the depth stencil format from the present parameters. - * The choice of the proper format can give a nice performance boost - * in case of GPU limited programs. */ - if(pPresentParms->EnableAutoDepthStencil) { - TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat)); - ds_format_desc = getFormatDescEntry(pPresentParms->AutoDepthStencilFormat, &This->adapter->gl_info); - } - - /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD */ - if(pPresentParms->MultiSampleType && (pPresentParms->SwapEffect == WINED3DSWAPEFFECT_DISCARD)) { - if (!gl_info->supported[ARB_MULTISAMPLE]) - ERR("The program is requesting multisampling without support!\n"); - else - { - TRACE("Requesting multisample type %#x.\n", pPresentParms->MultiSampleType); - numSamples = pPresentParms->MultiSampleType; - } - } - - /* Try to find a pixel format which matches our requirements */ - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, color_format_desc, ds_format_desc, - auxBuffers, numSamples, FALSE /* PBUFFER */, FALSE /* findCompatible */); - - /* Try to locate a compatible format if we weren't able to find anything */ - if(!iPixelFormat) { - TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); - iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, color_format_desc, ds_format_desc, - auxBuffers, 0 /* numSamples */, FALSE /* PBUFFER */, TRUE /* findCompatible */ ); - } - - /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */ - if(!iPixelFormat) { - ERR("Can't find a suitable iPixelFormat\n"); - return NULL; - } - - DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd); - res = SetPixelFormat(hdc, iPixelFormat, NULL); - if(!res) { - int oldPixelFormat = GetPixelFormat(hdc); - - /* By default WGL doesn't allow pixel format adjustments but we need it here. - * For this reason there is a WINE-specific wglSetPixelFormat which allows you to - * set the pixel format multiple times. Only use it when it is really needed. */ - - if(oldPixelFormat == iPixelFormat) { - /* We don't have to do anything as the formats are the same :) */ - } - else if (oldPixelFormat && gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH]) - { - res = GL_EXTCALL(wglSetPixelFormatWINE(hdc, iPixelFormat, NULL)); - - if(!res) { - ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat); - return NULL; - } - } else if(oldPixelFormat) { - /* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format. - * There's a big chance that the old format works although with a performance hit and perhaps rendering errors. */ - ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat); - } else { - ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat); - return NULL; - } + /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD. */ + if (swapchain->presentParms.MultiSampleType && (swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD)) + { + if (!gl_info->supported[ARB_MULTISAMPLE]) + WARN("The application is requesting multisampling without support.\n"); + else + { + TRACE("Requesting multisample type %#x.\n", swapchain->presentParms.MultiSampleType); + numSamples = swapchain->presentParms.MultiSampleType; } } - ctx = pwglCreateContext(hdc); - if (This->numContexts) + /* Try to find a pixel format which matches our requirements. */ + pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc, + auxBuffers, numSamples, FALSE /* findCompatible */); + + /* Try to locate a compatible format if we weren't able to find anything. */ + if (!pixel_format) { - if (!pwglShareLists(This->contexts[0]->glCtx, ctx)) + TRACE("Trying to locate a compatible pixel format because an exact match failed.\n"); + pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc, + auxBuffers, 0 /* numSamples */, TRUE /* findCompatible */); + } + + /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */ + if (!pixel_format) + { + ERR("Can't find a suitable pixel format.\n"); + goto out; + } + + DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd); + if (!context_set_pixel_format(gl_info, hdc, pixel_format)) + { + ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc); + goto out; + } + + ctx = pwglCreateContext(hdc); + if (device->numContexts) + { + if (!pwglShareLists(device->contexts[0]->glCtx, ctx)) { DWORD err = GetLastError(); ERR("wglShareLists(%p, %p) failed, last error %#x.\n", - This->contexts[0]->glCtx, ctx, err); + device->contexts[0]->glCtx, ctx, err); } } if(!ctx) { ERR("Failed to create a WGL context\n"); - if(create_pbuffer) { - GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc)); - GL_EXTCALL(wglDestroyPbufferARB(pbuffer)); - } goto out; } - ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer); - if(!ret) { + + if (!device_context_add(device, ret)) + { ERR("Failed to add the newly created context to the context list\n"); if (!pwglDeleteContext(ctx)) { DWORD err = GetLastError(); ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, err); } - if(create_pbuffer) { - GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc)); - GL_EXTCALL(wglDestroyPbufferARB(pbuffer)); - } goto out; } - ret->valid = 1; - ret->gl_info = &This->adapter->gl_info; - ret->surface = (IWineD3DSurface *) target; - ret->current_rt = (IWineD3DSurface *)target; - ret->render_offscreen = surface_is_offscreen((IWineD3DSurface *) target); - ret->draw_buffer_dirty = TRUE; + + ret->gl_info = gl_info; + + /* Mark all states dirty to force a proper initialization of the states + * on the first use of the context. */ + for (state = 0; state <= STATE_HIGHEST; ++state) + { + if (device->StateTable[state].representative) + Context_MarkStateDirty(ret, state, device->StateTable); + } + + ret->swapchain = swapchain; + ret->current_rt = target; ret->tid = GetCurrentThreadId(); - if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) { + + ret->render_offscreen = surface_is_offscreen(target); + ret->draw_buffer_dirty = TRUE; + ret->valid = 1; + + ret->glCtx = ctx; + ret->win_handle = swapchain->win_handle; + ret->hdc = hdc; + ret->pixel_format = pixel_format; + + if (device->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *)device)) + { /* Create the dirty constants array and initialize them to dirty */ ret->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, - sizeof(*ret->vshader_const_dirty) * This->d3d_vshader_constantF); + sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF); ret->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0, - sizeof(*ret->pshader_const_dirty) * This->d3d_pshader_constantF); + sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF); memset(ret->vshader_const_dirty, 1, - sizeof(*ret->vshader_const_dirty) * This->d3d_vshader_constantF); + sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF); memset(ret->pshader_const_dirty, 1, - sizeof(*ret->pshader_const_dirty) * This->d3d_pshader_constantF); + sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF); } + ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + gl_info->limits.buffers * sizeof(*ret->blit_targets)); + if (!ret->blit_targets) goto out; + ret->free_occlusion_query_size = 4; ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0, ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries)); @@ -1440,10 +1421,10 @@ struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurface glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); - glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment); - checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);"); - glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment); - checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);"); + glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment); + checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);"); + glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment); + checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);"); if (gl_info->supported[APPLE_CLIENT_STORAGE]) { @@ -1512,83 +1493,22 @@ struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurface LEAVE_GL(); - This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE); + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); + + TRACE("Created context %p.\n", ret); return ret; out: - if (ret) - { - HeapFree(GetProcessHeap(), 0, ret->free_event_queries); - HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); - HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty); - HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty); - HeapFree(GetProcessHeap(), 0, ret); - } + HeapFree(GetProcessHeap(), 0, ret->free_event_queries); + HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); + HeapFree(GetProcessHeap(), 0, ret->blit_targets); + HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty); + HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty); + HeapFree(GetProcessHeap(), 0, ret); return NULL; } -/***************************************************************************** - * RemoveContextFromArray - * - * Removes a context from the context manager. The opengl context is not - * destroyed or unset. context is not a valid pointer after that call. - * - * Similar to the former call this isn't a performance critical function. A - * helper function for context_destroy(). - * - * Params: - * This: Device to activate the context for - * context: Context to remove - * - *****************************************************************************/ -static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_context *context) -{ - struct wined3d_context **new_array; - BOOL found = FALSE; - UINT i; - - TRACE("Removing ctx %p\n", context); - - for (i = 0; i < This->numContexts; ++i) - { - if (This->contexts[i] == context) - { - found = TRUE; - break; - } - } - - if (!found) - { - ERR("Context %p doesn't exist in context array\n", context); - return; - } - - while (i < This->numContexts - 1) - { - This->contexts[i] = This->contexts[i + 1]; - ++i; - } - - --This->numContexts; - if (!This->numContexts) - { - HeapFree(GetProcessHeap(), 0, This->contexts); - This->contexts = NULL; - return; - } - - new_array = HeapReAlloc(GetProcessHeap(), 0, This->contexts, This->numContexts * sizeof(*This->contexts)); - if (!new_array) - { - ERR("Failed to shrink context array. Oh well.\n"); - return; - } - - This->contexts = new_array; -} - /***************************************************************************** * context_destroy * @@ -1617,9 +1537,10 @@ void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) destroy = FALSE; } + HeapFree(GetProcessHeap(), 0, context->blit_targets); HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty); HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty); - RemoveContextFromArray(This, context); + device_context_remove(This, context); if (destroy) HeapFree(GetProcessHeap(), 0, context); } @@ -1657,8 +1578,8 @@ static void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *conte int i; const struct StateEntry *StateTable = This->StateTable; const struct wined3d_gl_info *gl_info = context->gl_info; - UINT width = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Width; - UINT height = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height; + UINT width = context->current_rt->currentDesc.Width; + UINT height = context->current_rt->currentDesc.Height; DWORD sampler; TRACE("Setting up context %p for blitting\n", context); @@ -1811,6 +1732,9 @@ static void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *conte glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE); checkGLcall("glColorMask"); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), StateTable); if (gl_info->supported[EXT_SECONDARY_COLOR]) { glDisable(GL_COLOR_SUM_EXT); @@ -1882,14 +1806,12 @@ static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain * * Returns: The needed context * *****************************************************************************/ -static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target) +static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target) { IWineD3DSwapChain *swapchain = NULL; struct wined3d_context *current_context = context_get_current(); - const struct StateEntry *StateTable = This->StateTable; DWORD tid = GetCurrentThreadId(); struct wined3d_context *context; - BOOL old_render_offscreen; if (current_context && current_context->destroyed) current_context = NULL; @@ -1897,15 +1819,15 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur { if (current_context && current_context->current_rt - && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This) + && current_context->swapchain->device == This) { target = current_context->current_rt; } else { IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0]; - if (swapchain->backBuffer) target = swapchain->backBuffer[0]; - else target = swapchain->frontBuffer; + if (swapchain->back_buffers) target = swapchain->back_buffers[0]; + else target = swapchain->front_buffer; } } @@ -1915,165 +1837,36 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur return current_context; } - if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain))) { + if (target->Flags & SFLAG_SWAPCHAIN) + { TRACE("Rendering onscreen\n"); + swapchain = (IWineD3DSwapChain *)target->container; context = findThreadContextForSwapChain(swapchain, tid); - - old_render_offscreen = context->render_offscreen; - context->render_offscreen = surface_is_offscreen(target); - /* The context != This->activeContext will catch a NOP context change. This can occur - * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen - * rendering. No context change is needed in that case - */ - - if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) { - if(This->pbufferContext && tid == This->pbufferContext->tid) { - This->pbufferContext->tid = 0; - } - } - IWineD3DSwapChain_Release(swapchain); } else { TRACE("Rendering offscreen\n"); -retry: - if (wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) + /* Stay with the currently active context. */ + if (current_context && current_context->swapchain->device == This) { - IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *)target; - if (!This->pbufferContext - || This->pbufferWidth < targetimpl->currentDesc.Width - || This->pbufferHeight < targetimpl->currentDesc.Height) - { - if (This->pbufferContext) context_destroy(This, This->pbufferContext); - - /* The display is irrelevant here, the window is 0. But - * context_create() needs a valid X connection. Create the context - * on the same server as the primary swapchain. The primary - * swapchain is exists at this point. */ - This->pbufferContext = context_create(This, targetimpl, - ((IWineD3DSwapChainImpl *)This->swapchains[0])->context[0]->win_handle, - TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms); - This->pbufferWidth = targetimpl->currentDesc.Width; - This->pbufferHeight = targetimpl->currentDesc.Height; - if (This->pbufferContext) context_release(This->pbufferContext); - } - - if (This->pbufferContext) - { - if (This->pbufferContext->tid && This->pbufferContext->tid != tid) - { - FIXME("The PBuffer context is only supported for one thread for now!\n"); - } - This->pbufferContext->tid = tid; - context = This->pbufferContext; - } - else - { - ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering.\n"); - wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; - goto retry; - } + context = current_context; } else { - /* Stay with the currently active context. */ - if (current_context - && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.device == This) - { - context = current_context; - } - else - { - /* This may happen if the app jumps straight into offscreen rendering - * Start using the context of the primary swapchain. tid == 0 is no problem - * for findThreadContextForSwapChain. - * - * Can also happen on thread switches - in that case findThreadContextForSwapChain - * is perfect to call. */ - context = findThreadContextForSwapChain(This->swapchains[0], tid); - } + /* This may happen if the app jumps straight into offscreen rendering + * Start using the context of the primary swapchain. tid == 0 is no problem + * for findThreadContextForSwapChain. + * + * Can also happen on thread switches - in that case findThreadContextForSwapChain + * is perfect to call. */ + context = findThreadContextForSwapChain(This->swapchains[0], tid); } - - old_render_offscreen = context->render_offscreen; - context->render_offscreen = TRUE; } context_validate(context); - if (context->render_offscreen != old_render_offscreen) - { - Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable); - Context_MarkStateDirty(context, STATE_VDECL, StateTable); - Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); - Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); - Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable); - } - - /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers - * the alpha blend state changes with different render target formats. */ - if (!context->current_rt) - { - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); - } - else - { - const struct GlPixelFormatDesc *old = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.format_desc; - const struct GlPixelFormatDesc *new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc; - - if (old->format != new->format) - { - /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ - if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask) - || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) - { - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); - } - } - - /* When switching away from an offscreen render target, and we're not - * using FBOs, we have to read the drawable into the texture. This is - * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There - * are some things that need care though. PreLoad needs a GL context, - * and FindContext is called before the context is activated. It also - * has to be called with the old rendertarget active, otherwise a - * wrong drawable is read. */ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO - && old_render_offscreen && context->current_rt != target) - { - BOOL oldInDraw = This->isInDraw; - - /* surface_internal_preload() requires a context to load the - * texture, so it will call context_acquire(). Set isInDraw to true - * to signal surface_internal_preload() that it has a context. */ - - /* FIXME: This is just broken. There's no guarantee whatsoever - * that the currently active context, if any, is appropriate for - * reading back the render target. We should probably call - * context_set_current(context) here and then rely on - * context_acquire() doing the right thing. */ - This->isInDraw = TRUE; - - /* Read the back buffer of the old drawable into the destination texture. */ - if (((IWineD3DSurfaceImpl *)context->current_rt)->texture_name_srgb) - { - surface_internal_preload(context->current_rt, SRGB_BOTH); - } - else - { - surface_internal_preload(context->current_rt, SRGB_RGB); - } - - IWineD3DSurface_ModifyLocation(context->current_rt, SFLAG_INDRAWABLE, FALSE); - - This->isInDraw = oldInDraw; - } - } - - context->draw_buffer_dirty = TRUE; - context->current_rt = target; - return context; } @@ -2081,10 +1874,10 @@ retry: static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit) { const struct wined3d_gl_info *gl_info = context->gl_info; - IWineD3DSurface *rt = context->current_rt; + IWineD3DSurfaceImpl *rt = context->current_rt; IWineD3DDeviceImpl *device; - device = ((IWineD3DSurfaceImpl *)rt)->resource.device; + device = rt->resource.device; if (!surface_is_offscreen(rt)) { ENTER_GL(); @@ -2099,6 +1892,16 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit { if (!blit) { + unsigned int i; + + for (i = 0; i < gl_info->limits.buffers; ++i) + { + if (device->render_targets[i]) + device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i; + else + device->draw_buffers[i] = GL_NONE; + } + if (gl_info->supported[ARB_DRAW_BUFFERS]) { GL_EXTCALL(glDrawBuffersARB(gl_info->limits.buffers, device->draw_buffers)); @@ -2131,116 +1934,268 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) context->draw_buffer_dirty = TRUE; } +static inline void context_set_render_offscreen(struct wined3d_context *context, const struct StateEntry *StateTable, + BOOL offscreen) +{ + if (context->render_offscreen == offscreen) return; + + Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable); + Context_MarkStateDirty(context, STATE_VDECL, StateTable); + Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable); + Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); + Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable); + context->render_offscreen = offscreen; +} + +static BOOL match_depth_stencil_format(const struct wined3d_format_desc *existing, + const struct wined3d_format_desc *required) +{ + short existing_depth, existing_stencil, required_depth, required_stencil; + + if(existing == required) return TRUE; + if((existing->Flags & WINED3DFMT_FLAG_FLOAT) != (required->Flags & WINED3DFMT_FLAG_FLOAT)) return FALSE; + + getDepthStencilBits(existing, &existing_depth, &existing_stencil); + getDepthStencilBits(required, &required_depth, &required_stencil); + + if(existing_depth < required_depth) return FALSE; + /* If stencil bits are used the exact amount is required - otherwise wrapping + * won't work correctly */ + if(required_stencil && required_stencil != existing_stencil) return FALSE; + return TRUE; +} +/* The caller provides a context */ +static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device, + struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil) +{ + /* Onscreen surfaces are always in a swapchain */ + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)context->current_rt->container; + + if (context->render_offscreen || !depth_stencil) return; + if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return; + + /* TODO: If the requested format would satisfy the needs of the existing one(reverse match), + * or no onscreen depth buffer was created, the OpenGL drawable could be changed to the new + * format. */ + WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); + + /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ + IWineD3DSurface_LoadLocation((IWineD3DSurface *)context->current_rt, SFLAG_INTEXTURE, NULL); + swapchain->render_to_fbo = TRUE; + context_set_render_offscreen(context, device->StateTable, TRUE); +} + /* Context activation is done by the caller. */ -static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, enum ContextUsage usage) +void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) +{ + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + context_validate_onscreen_formats(device, context, NULL); + + if (context->render_offscreen) + { + FIXME("Applying blit state for an offscreen target with ORM_FBO. This should be avoided.\n"); + surface_internal_preload(context->current_rt, SRGB_RGB); + + ENTER_GL(); + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, context->current_rt, NULL); + LEAVE_GL(); + } + else + { + ENTER_GL(); + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + LEAVE_GL(); + } + + context->draw_buffer_dirty = TRUE; + } + + if (context->draw_buffer_dirty) + { + context_apply_draw_buffer(context, TRUE); + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + context->draw_buffer_dirty = FALSE; + } + + SetupForBlit(device, context); +} + +/* Context activation is done by the caller. */ +void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) +{ + const struct StateEntry *state_table = device->StateTable; + GLenum buffer; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + context_validate_onscreen_formats(device, context, depth_stencil); + + ENTER_GL(); + context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, render_target, depth_stencil); + LEAVE_GL(); + } + + if (!surface_is_offscreen(render_target)) + buffer = surface_get_gl_buffer(render_target); + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + buffer = GL_COLOR_ATTACHMENT0; + else + buffer = device->offscreenBuffer; + + ENTER_GL(); + context_set_draw_buffer(context, buffer); + LEAVE_GL(); + + if (context->last_was_blit) + { + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); + } + + /* Blending and clearing should be orthogonal, but tests on the nvidia + * driver show that disabling blending when clearing improves the clearing + * performance incredibly. */ + ENTER_GL(); + glDisable(GL_BLEND); + glEnable(GL_SCISSOR_TEST); + checkGLcall("glEnable GL_SCISSOR_TEST"); + LEAVE_GL(); + + context->last_was_blit = FALSE; + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); + Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); +} + +/* Context activation is done by the caller. */ +void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) { const struct StateEntry *state_table = device->StateTable; unsigned int i; - switch (usage) { - case CTXUSAGE_CLEAR: - case CTXUSAGE_DRAWPRIM: - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - ENTER_GL(); - context_apply_fbo_state(context); - LEAVE_GL(); - } - if (context->draw_buffer_dirty) { - context_apply_draw_buffer(context, FALSE); - context->draw_buffer_dirty = FALSE; - } - break; + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + context_validate_onscreen_formats(device, context, device->depth_stencil); - case CTXUSAGE_BLIT: - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (context->render_offscreen) - { - FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n"); - surface_internal_preload(context->current_rt, SRGB_RGB); - - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); - LEAVE_GL(); - } else { - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - LEAVE_GL(); - } - context->draw_buffer_dirty = TRUE; - } - if (context->draw_buffer_dirty) { - context_apply_draw_buffer(context, TRUE); - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) { - context->draw_buffer_dirty = FALSE; - } - } - break; - - default: - break; + if (!context->render_offscreen) + { + ENTER_GL(); + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL); + LEAVE_GL(); + } + else + { + ENTER_GL(); + context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil); + LEAVE_GL(); + } } - switch(usage) { - case CTXUSAGE_RESOURCELOAD: - /* This does not require any special states to be set up */ - break; + if (context->draw_buffer_dirty) + { + context_apply_draw_buffer(context, FALSE); + context->draw_buffer_dirty = FALSE; + } - case CTXUSAGE_CLEAR: - if(context->last_was_blit) { - device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); - } + if (context->last_was_blit) + { + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); + } - /* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling - * blending when clearing improves the clearing performance incredibly. - */ - ENTER_GL(); - glDisable(GL_BLEND); - LEAVE_GL(); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table); + IWineD3DDeviceImpl_FindTexUnitMap(device); + device_preload_textures(device); + if (isStateDirty(context, STATE_VDECL)) + device_update_stream_info(device, context->gl_info); - ENTER_GL(); - glEnable(GL_SCISSOR_TEST); - checkGLcall("glEnable GL_SCISSOR_TEST"); - LEAVE_GL(); - context->last_was_blit = FALSE; - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); - Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); - break; + ENTER_GL(); + for (i = 0; i < context->numDirtyEntries; ++i) + { + DWORD rep = context->dirtyArray[i]; + DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); + BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); + context->isStateDirty[idx] &= ~(1 << shift); + state_table[rep].apply(rep, device->stateBlock, context); + } + LEAVE_GL(); + context->numDirtyEntries = 0; /* This makes the whole list clean */ + context->last_was_blit = FALSE; +} - case CTXUSAGE_DRAWPRIM: - /* This needs all dirty states applied */ - if(context->last_was_blit) { - device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); - } +static void context_setup_target(IWineD3DDeviceImpl *device, + struct wined3d_context *context, IWineD3DSurfaceImpl *target) +{ + BOOL old_render_offscreen = context->render_offscreen, render_offscreen; + const struct StateEntry *StateTable = device->StateTable; - IWineD3DDeviceImpl_FindTexUnitMap(device); - device_preload_textures(device); - if (isStateDirty(context, STATE_VDECL)) - device_update_stream_info(device, context->gl_info); + if (!target) return; + else if (context->current_rt == target) return; + render_offscreen = surface_is_offscreen(target); - ENTER_GL(); - for (i = 0; i < context->numDirtyEntries; ++i) + context_set_render_offscreen(context, StateTable, render_offscreen); + + /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers + * the alpha blend state changes with different render target formats. */ + if (!context->current_rt) + { + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); + } + else + { + const struct wined3d_format_desc *old = context->current_rt->resource.format_desc; + const struct wined3d_format_desc *new = target->resource.format_desc; + + if (old->format != new->format) + { + /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */ + if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask) + || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) { - DWORD rep = context->dirtyArray[i]; - DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); - BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); - context->isStateDirty[idx] &= ~(1 << shift); - state_table[rep].apply(rep, device->stateBlock, context); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); } - LEAVE_GL(); - context->numDirtyEntries = 0; /* This makes the whole list clean */ - context->last_was_blit = FALSE; - break; + } - case CTXUSAGE_BLIT: - SetupForBlit(device, context); - break; + /* When switching away from an offscreen render target, and we're not + * using FBOs, we have to read the drawable into the texture. This is + * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There + * are some things that need care though. PreLoad needs a GL context, + * and FindContext is called before the context is activated. It also + * has to be called with the old rendertarget active, otherwise a + * wrong drawable is read. */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO + && old_render_offscreen && context->current_rt != target) + { + BOOL oldInDraw = device->isInDraw; - default: - FIXME("Unexpected context usage requested\n"); + /* surface_internal_preload() requires a context to load the + * texture, so it will call context_acquire(). Set isInDraw to true + * to signal surface_internal_preload() that it has a context. */ + + /* FIXME: This is just broken. There's no guarantee whatsoever + * that the currently active context, if any, is appropriate for + * reading back the render target. We should probably call + * context_set_current(context) here and then rely on + * context_acquire() doing the right thing. */ + device->isInDraw = TRUE; + + /* Read the back buffer of the old drawable into the destination texture. */ + if (context->current_rt->texture_name_srgb) + { + surface_internal_preload(context->current_rt, SRGB_BOTH); + } + else + { + surface_internal_preload(context->current_rt, SRGB_RGB); + } + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)context->current_rt, SFLAG_INDRAWABLE, FALSE); + + device->isInDraw = oldInDraw; + } } + + context->draw_buffer_dirty = TRUE; + context->current_rt = target; } /***************************************************************************** @@ -2256,14 +2211,15 @@ static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceI * usage: Prepares the context for blitting, drawing or other actions * *****************************************************************************/ -struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurface *target, enum ContextUsage usage) +struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *target) { struct wined3d_context *current_context = context_get_current(); struct wined3d_context *context; - TRACE("device %p, target %p, usage %#x.\n", device, target, usage); + TRACE("device %p, target %p.\n", device, target); context = FindContext(device, target); + context_setup_target(device, context, target); context_enter(context); if (!context->valid) return context; @@ -2295,7 +2251,5 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurf } } - context_apply_state(context, device, usage); - return context; } diff --git a/dll/directx/wine/wined3d/cubetexture.c b/dll/directx/wine/wined3d/cubetexture.c index c5fa6ba280f..12acee26573 100644 --- a/dll/directx/wine/wined3d/cubetexture.c +++ b/dll/directx/wine/wined3d/cubetexture.c @@ -31,11 +31,12 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 { /* Override the IWineD3DResource Preload method. */ IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; IWineD3DDeviceImpl *device = This->resource.device; struct wined3d_context *context = NULL; - unsigned int i, j; BOOL srgb_mode; BOOL *dirty; + UINT i; switch (srgb) { @@ -66,25 +67,24 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 { /* No danger of recursive calls, context_acquire() sets isInDraw to true * when loading offscreen render targets into their texture. */ - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } if (This->resource.format_desc->format == WINED3DFMT_P8_UINT || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < sub_count; ++i) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + + if (palette9_changed(surface)) { - if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[j][i])) - { - TRACE("Reloading surface because the d3d8/9 palette was changed.\n"); - /* TODO: This is not necessarily needed with hw palettized texture support. */ - IWineD3DSurface_LoadLocation(This->surfaces[j][i], SFLAG_INSYSMEM, NULL); - /* Make sure the texture is reloaded because of the palette change, - * this kills performance though :( */ - IWineD3DSurface_ModifyLocation(This->surfaces[j][i], SFLAG_INTEXTURE, FALSE); - } + TRACE("Reloading surface %p because the d3d8/9 palette was changed.\n", surface); + /* TODO: This is not necessarily needed with hw palettized texture support. */ + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); + /* Make sure the texture is reloaded because of the palette change, + * this kills performance though :( */ + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); } } } @@ -93,12 +93,9 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 * since the last load then reload the surfaces. */ if (*dirty) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < sub_count; ++i) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) - { - IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode); - } + IWineD3DSurface_LoadTexture((IWineD3DSurface *)This->baseTexture.sub_resources[i], srgb_mode); } } else @@ -114,26 +111,24 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3 static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This) { - unsigned int i, j; + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; + UINT i; TRACE("(%p) : Cleaning up.\n", This); - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < sub_count; ++i) { - for (j = 0; j < 6; ++j) - { - IWineD3DSurface *surface = This->surfaces[j][i]; + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; - if (surface) - { - /* Clean out the texture name we gave to the surface so that the - * surface doesn't try and release it. */ - surface_set_texture_name(surface, 0, TRUE); - surface_set_texture_name(surface, 0, FALSE); - surface_set_texture_target(surface, 0); - IWineD3DSurface_SetContainer(surface, NULL); - IWineD3DSurface_Release(surface); - } + if (surface) + { + /* Clean out the texture name we gave to the surface so that the + * surface doesn't try and release it. */ + surface_set_texture_name(surface, 0, TRUE); + surface_set_texture_name(surface, 0, FALSE); + surface_set_texture_target(surface, 0); + IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL); + IWineD3DSurface_Release((IWineD3DSurface *)surface); } } basetexture_cleanup((IWineD3DBaseTexture *)This); @@ -207,21 +202,25 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) { cubetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY); } -static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) { - unsigned int i, j; +static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) +{ IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - TRACE("(%p)\n", This); + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; + UINT i; + + TRACE("iface %p.\n", iface); /* Unload all the surfaces and reset the texture name. If UnLoad was called on the * surface before, this one will be a NOP and vice versa. Unloading an unloaded - * surface is fine - */ - for (i = 0; i < This->baseTexture.levels; i++) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) { - IWineD3DSurface_UnLoad(This->surfaces[j][i]); - surface_set_texture_name(This->surfaces[j][i], 0, TRUE); - surface_set_texture_name(This->surfaces[j][i], 0, FALSE); - } + * surface is fine. */ + + for (i = 0; i < sub_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + + IWineD3DSurface_UnLoad((IWineD3DSurface *)surface); + surface_set_texture_name(surface, 0, TRUE); + surface_set_texture_name(surface, 0, FALSE); } basetexture_unload((IWineD3DBaseTexture *)iface); @@ -281,16 +280,19 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *i TRACE("(%p) : relay to BaseTexture\n", This); hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc); - if (set_gl_texture_desc && SUCCEEDED(hr)) { - UINT i, j; - for (i = 0; i < This->baseTexture.levels; ++i) { - for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) { - if(This->baseTexture.is_srgb) { - surface_set_texture_name(This->surfaces[j][i], This->baseTexture.texture_srgb.name, TRUE); - } else { - surface_set_texture_name(This->surfaces[j][i], This->baseTexture.texture_rgb.name, FALSE); - } - } + if (set_gl_texture_desc && SUCCEEDED(hr)) + { + UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count; + UINT i; + + for (i = 0; i < sub_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + + if (This->baseTexture.is_srgb) + surface_set_texture_name(surface, This->baseTexture.texture_srgb.name, TRUE); + else + surface_set_texture_name(surface, This->baseTexture.texture_rgb.name, FALSE); } } @@ -314,82 +316,102 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface) /* ******************************************* IWineD3DCubeTexture IWineD3DCubeTexture parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) { - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, + UINT level, WINED3DSURFACE_DESC *desc) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - TRACE("(%p) level (%d)\n", This, Level); - return IWineD3DSurface_GetDesc(This->surfaces[0][Level], pDesc); + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + + return IWineD3DSurface_GetDesc(surface, desc); } -static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, IWineD3DSurface** ppCubeMapSurface) { - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, UINT level, IWineD3DSurface **surface) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *s; - if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - *ppCubeMapSurface = This->surfaces[FaceType][Level]; - IWineD3DSurface_AddRef(*ppCubeMapSurface); + TRACE("iface %p, face %u, level %u, surface %p.\n", + iface, face, level, surface); - hr = WINED3D_OK; - } - if (WINED3D_OK == hr) { - TRACE("(%p) -> faceType(%d) level(%d) returning surface@%p\n", This, FaceType, Level, This->surfaces[FaceType][Level]); - } else { - WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType); + if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + IWineD3DSurface_AddRef(s); + *surface = s; + + TRACE("Returning surface %p.\n", *surface); + + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { - HRESULT hr = WINED3DERR_INVALIDCALL; - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, UINT level, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - hr = IWineD3DSurface_LockRect(This->surfaces[FaceType][Level], pLockedRect, pRect, Flags); + TRACE("iface %p, face %u, level %u, locked_rect %p, rect %s, flags %#x.\n", + iface, face, level, locked_rect, wine_dbgstr_rect(rect), flags); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if (WINED3D_OK == hr) { - TRACE("(%p) -> faceType(%d) level(%d) returning memory@%p success(%u)\n", This, FaceType, Level, pLockedRect->pBits, hr); - } else { - WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType); - } - - return hr; + return IWineD3DSurface_LockRect(surface, locked_rect, rect, flags); } -static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level) { - HRESULT hr = WINED3DERR_INVALIDCALL; - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, UINT level) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - hr = IWineD3DSurface_UnlockRect(This->surfaces[FaceType][Level]); + TRACE("iface %p, face %u, level %u.\n", + iface, face, level); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, face, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if (WINED3D_OK == hr) { - TRACE("(%p) -> faceType(%d) level(%d) success(%u)\n", This, FaceType, Level, hr); - } else { - WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType); - } - return hr; + return IWineD3DSurface_UnlockRect(surface); } -static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) { - HRESULT hr = WINED3DERR_INVALIDCALL; - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - This->baseTexture.texture_rgb.dirty = TRUE; - This->baseTexture.texture_srgb.dirty = TRUE; - TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType); - if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { - surface_add_dirty_rect(This->surfaces[FaceType][0], pDirtyRect); - hr = WINED3D_OK; - } else { - WARN("(%p) overflow FaceType(%d)\n", This, FaceType); +static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, + WINED3DCUBEMAP_FACES face, const RECT *dirty_rect) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurfaceImpl *surface; + + TRACE("iface %p, face %u, dirty_rect %s.\n", + iface, face, wine_dbgstr_rect(dirty_rect)); + + if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, face, 0))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + + texture->baseTexture.texture_rgb.dirty = TRUE; + texture->baseTexture.texture_srgb.dirty = TRUE; + surface_add_dirty_rect(surface, dirty_rect); + + return WINED3D_OK; } static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = @@ -433,7 +455,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT pow2_edge_length; unsigned int i, j; UINT tmp_w; @@ -478,8 +500,8 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN texture->lpVtbl = &IWineD3DCubeTexture_Vtbl; - hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_CUBETEXTURE, - device, 0, usage, format_desc, pool, parent, parent_ops); + hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 6, levels, + WINED3DRTYPE_CUBETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x\n", hr); @@ -510,7 +532,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN /* Generate all the surfaces. */ tmp_w = edge_length; - for (i = 0; i < texture->baseTexture.levels; ++i) + for (i = 0; i < texture->baseTexture.level_count; ++i) { /* Create the 6 faces. */ for (j = 0; j < 6; ++j) @@ -524,20 +546,22 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, }; + UINT idx = j * texture->baseTexture.level_count + i; + IWineD3DSurface *surface; hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_w, - format, usage, pool, i /* Level */, j, &texture->surfaces[j][i]); + format, usage, pool, i /* Level */, j, &surface); if (FAILED(hr)) { FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr); - texture->surfaces[j][i] = NULL; cubetexture_cleanup(texture); return hr; } - IWineD3DSurface_SetContainer(texture->surfaces[j][i], (IWineD3DBase *)texture); - TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[j][i]); - surface_set_texture_target(texture->surfaces[j][i], cube_targets[j]); + IWineD3DSurface_SetContainer(surface, (IWineD3DBase *)texture); + surface_set_texture_target((IWineD3DSurfaceImpl *)surface, cube_targets[j]); + texture->baseTexture.sub_resources[idx] = (IWineD3DResourceImpl *)surface; + TRACE("Created surface level %u @ %p.\n", i, surface); } tmp_w = max(1, tmp_w >> 1); } diff --git a/dll/directx/wine/wined3d/device.c b/dll/directx/wine/wined3d/device.c index 6682aa4635e..7eb9153fca9 100644 --- a/dll/directx/wine/wined3d/device.c +++ b/dll/directx/wine/wined3d/device.c @@ -34,7 +34,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION This->adapter->gl_info /* Define the default light parameters as specified by MSDN */ const WINED3DLIGHT WINED3D_default_light = { @@ -213,7 +212,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, else { TRACE("Stream %u isn't UP, %p\n", element->input_slot, This->stateBlock->streamSource[element->input_slot]); - data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], 0, &buffer_object); + data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], + &This->adapter->gl_info, &buffer_object); /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory @@ -224,7 +224,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); buffer_object = 0; - data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot]); + data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot], + &This->adapter->gl_info); if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) { FIXME("System memory vertex data load offset is negative!\n"); @@ -305,6 +306,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, } } + This->num_buffer_queries = 0; if (!This->stateBlock->streamIsUP) { WORD map = stream_info->use_map; @@ -314,6 +316,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { struct wined3d_stream_info_element *element; struct wined3d_buffer *buffer; + struct wined3d_event_query *query; if (!(map & 1)) continue; @@ -325,7 +328,13 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, if (buffer->buffer_object != element->buffer_object) { element->buffer_object = 0; - element->data = buffer_get_sysmem(buffer) + (ptrdiff_t)element->data; + element->data = buffer_get_sysmem(buffer, &This->adapter->gl_info) + (ptrdiff_t)element->data; + } + + query = ((struct wined3d_buffer *) buffer)->query; + if(query) + { + This->buffer_queries[This->num_buffer_queries++] = query; } } } @@ -334,7 +343,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, static void stream_info_element_from_strided(const struct wined3d_gl_info *gl_info, const struct WineDirect3DStridedData *strided, struct wined3d_stream_info_element *e) { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(strided->format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(strided->format, gl_info); e->format_desc = format_desc; e->stride = strided->dwStride; e->data = strided->lpData; @@ -494,6 +503,95 @@ void device_preload_textures(IWineD3DDeviceImpl *device) } } +BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) +{ + struct wined3d_context **new_array; + + TRACE("Adding context %p.\n", context); + + if (!device->contexts) new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array)); + else new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, sizeof(*new_array) * (device->numContexts + 1)); + + if (!new_array) + { + ERR("Failed to grow the context array.\n"); + return FALSE; + } + + new_array[device->numContexts++] = context; + device->contexts = new_array; + return TRUE; +} + +void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) +{ + struct wined3d_context **new_array; + BOOL found = FALSE; + UINT i; + + TRACE("Removing context %p.\n", context); + + for (i = 0; i < device->numContexts; ++i) + { + if (device->contexts[i] == context) + { + found = TRUE; + break; + } + } + + if (!found) + { + ERR("Context %p doesn't exist in context array.\n", context); + return; + } + + if (!--device->numContexts) + { + HeapFree(GetProcessHeap(), 0, device->contexts); + device->contexts = NULL; + return; + } + + memmove(&device->contexts[i], &device->contexts[i + 1], (device->numContexts - i) * sizeof(*device->contexts)); + new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, device->numContexts * sizeof(*device->contexts)); + if (!new_array) + { + ERR("Failed to shrink context array. Oh well.\n"); + return; + } + + device->contexts = new_array; +} + +void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) +{ + IWineD3DStateBlockImpl *stateblock = device->stateBlock; + WINED3DVIEWPORT *vp = &stateblock->viewport; + + SetRect(rect, vp->X, vp->Y, vp->X + vp->Width, vp->Y + vp->Height); + + if (stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) + { + IntersectRect(rect, rect, &stateblock->scissorRect); + } +} + +void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, + struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil) +{ + if (device->onscreen_depth_stencil) + { + surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_DS_OFFSCREEN); + surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_DS_OFFSCREEN, + device->onscreen_depth_stencil->ds_current_size.cx, + device->onscreen_depth_stencil->ds_current_size.cy); + IWineD3DSurface_Release((IWineD3DSurface *)device->onscreen_depth_stencil); + } + device->onscreen_depth_stencil = depth_stencil; + IWineD3DSurface_AddRef((IWineD3DSurface *)device->onscreen_depth_stencil); +} + /********************************************************** * IUnknown parts follows **********************************************************/ @@ -540,9 +638,17 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) { /* NOTE: You must release the parent if the object was created via a callback ** ***************************/ - if (!list_empty(&This->resources)) { + if (!list_empty(&This->resources)) + { + IWineD3DResourceImpl *resource; FIXME("(%p) Device released with resources still bound, acceptable but unexpected\n", This); - dumpResources(&This->resources); + + LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry) + { + WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource); + FIXME("Leftover resource %p with type %s (%#x).\n", + resource, debug_d3dresourcetype(type), type); + } } if(This->contexts) ERR("Context array not freed!\n"); @@ -760,6 +866,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice * { struct wined3d_rendertarget_view *object; + TRACE("iface %p, resource %p, parent %p, rendertarget_view %p.\n", + iface, resource, parent, rendertarget_view); + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { @@ -767,12 +876,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice * return E_OUTOFMEMORY; } - object->vtbl = &wined3d_rendertarget_view_vtbl; - object->refcount = 1; - IWineD3DResource_AddRef(resource); - object->resource = resource; - object->parent = parent; + wined3d_rendertarget_view_init(object, resource, parent); + TRACE("Created render target view %p.\n", object); *rendertarget_view = (IWineD3DRendertargetView *)object; return WINED3D_OK; @@ -1030,11 +1136,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice return WINED3D_OK; } -static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */ - DWORD fvf, WINED3DVERTEXELEMENT** ppVertexElements) { +struct wined3d_fvf_convert_state +{ + const struct wined3d_gl_info *gl_info; + WINED3DVERTEXELEMENT *elements; + UINT offset; + UINT idx; +}; - unsigned int idx, idx2; - unsigned int offset; +static void append_decl_element(struct wined3d_fvf_convert_state *state, + WINED3DFORMAT format, WINED3DDECLUSAGE usage, UINT usage_idx) +{ + WINED3DVERTEXELEMENT *elements = state->elements; + const struct wined3d_format_desc *format_desc; + UINT offset = state->offset; + UINT idx = state->idx; + + elements[idx].format = format; + elements[idx].input_slot = 0; + elements[idx].offset = offset; + elements[idx].output_slot = 0; + elements[idx].method = WINED3DDECLMETHOD_DEFAULT; + elements[idx].usage = usage; + elements[idx].usage_idx = usage_idx; + + format_desc = getFormatDescEntry(format, state->gl_info); + state->offset += format_desc->component_count * format_desc->component_size; + ++state->idx; +} + +static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */ + DWORD fvf, WINED3DVERTEXELEMENT **ppVertexElements) +{ + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; BOOL has_pos = (fvf & WINED3DFVF_POSITION_MASK) != 0; BOOL has_blend = (fvf & WINED3DFVF_XYZB5) > WINED3DFVF_XYZRHW; BOOL has_blend_idx = has_blend && @@ -1048,9 +1182,9 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the DWORD num_textures = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT; DWORD texcoords = (fvf & 0xFFFF0000) >> 16; - WINED3DVERTEXELEMENT *elements = NULL; - + struct wined3d_fvf_convert_state state; unsigned int size; + unsigned int idx; DWORD num_blends = 1 + (((fvf & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1); if (has_blend_idx) num_blends--; @@ -1058,112 +1192,84 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal + has_psize + has_diffuse + has_specular + num_textures; - /* convert the declaration */ - elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WINED3DVERTEXELEMENT)); - if (!elements) return ~0U; + state.gl_info = gl_info; + state.elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*state.elements)); + if (!state.elements) return ~0U; + state.offset = 0; + state.idx = 0; - idx = 0; - if (has_pos) { - if (!has_blend && (fvf & WINED3DFVF_XYZRHW)) { - elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_POSITIONT; - } - else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) { - elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_POSITION; - } - else { - elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_POSITION; - } - elements[idx].usage_idx = 0; - idx++; + if (has_pos) + { + if (!has_blend && (fvf & WINED3DFVF_XYZRHW)) + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITIONT, 0); + else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_POSITION, 0); + else + append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_POSITION, 0); } - if (has_blend && (num_blends > 0)) { - if (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)) - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; - else { - switch(num_blends) { - case 1: elements[idx].format = WINED3DFMT_R32_FLOAT; break; - case 2: elements[idx].format = WINED3DFMT_R32G32_FLOAT; break; - case 3: elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; break; - case 4: elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; break; + + if (has_blend && (num_blends > 0)) + { + if ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)) + append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + else + { + switch (num_blends) + { + case 1: + append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 2: + append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 3: + append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; + case 4: + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_BLENDWEIGHT, 0); + break; default: ERR("Unexpected amount of blend values: %u\n", num_blends); } } - elements[idx].usage = WINED3DDECLUSAGE_BLENDWEIGHT; - elements[idx].usage_idx = 0; - idx++; } - if (has_blend_idx) { - if (fvf & WINED3DFVF_LASTBETA_UBYTE4 || - (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2) && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))) - elements[idx].format = WINED3DFMT_R8G8B8A8_UINT; + + if (has_blend_idx) + { + if ((fvf & WINED3DFVF_LASTBETA_UBYTE4) + || ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))) + append_decl_element(&state, WINED3DFMT_R8G8B8A8_UINT, WINED3DDECLUSAGE_BLENDINDICES, 0); else if (fvf & WINED3DFVF_LASTBETA_D3DCOLOR) - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; + append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_BLENDINDICES, 0); else - elements[idx].format = WINED3DFMT_R32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_BLENDINDICES; - elements[idx].usage_idx = 0; - idx++; + append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_BLENDINDICES, 0); } - if (has_normal) { - elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_NORMAL; - elements[idx].usage_idx = 0; - idx++; - } - if (has_psize) { - elements[idx].format = WINED3DFMT_R32_FLOAT; - elements[idx].usage = WINED3DDECLUSAGE_PSIZE; - elements[idx].usage_idx = 0; - idx++; - } - if (has_diffuse) { - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; - elements[idx].usage = WINED3DDECLUSAGE_COLOR; - elements[idx].usage_idx = 0; - idx++; - } - if (has_specular) { - elements[idx].format = WINED3DFMT_B8G8R8A8_UNORM; - elements[idx].usage = WINED3DDECLUSAGE_COLOR; - elements[idx].usage_idx = 1; - idx++; - } - for (idx2 = 0; idx2 < num_textures; idx2++) { - unsigned int numcoords = (texcoords >> (idx2*2)) & 0x03; - switch (numcoords) { + + if (has_normal) append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_NORMAL, 0); + if (has_psize) append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_PSIZE, 0); + if (has_diffuse) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 0); + if (has_specular) append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3DDECLUSAGE_COLOR, 1); + + for (idx = 0; idx < num_textures; ++idx) + { + switch ((texcoords >> (idx * 2)) & 0x03) + { case WINED3DFVF_TEXTUREFORMAT1: - elements[idx].format = WINED3DFMT_R32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; case WINED3DFVF_TEXTUREFORMAT2: - elements[idx].format = WINED3DFMT_R32G32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; case WINED3DFVF_TEXTUREFORMAT3: - elements[idx].format = WINED3DFMT_R32G32B32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; case WINED3DFVF_TEXTUREFORMAT4: - elements[idx].format = WINED3DFMT_R32G32B32A32_FLOAT; + append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3DDECLUSAGE_TEXCOORD, idx); break; } - elements[idx].usage = WINED3DDECLUSAGE_TEXCOORD; - elements[idx].usage_idx = idx2; - idx++; } - /* Now compute offsets, and initialize the rest of the fields */ - for (idx = 0, offset = 0; idx < size; ++idx) - { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(elements[idx].format, &This->adapter->gl_info); - elements[idx].input_slot = 0; - elements[idx].method = WINED3DDECLMETHOD_DEFAULT; - elements[idx].offset = offset; - offset += format_desc->component_count * format_desc->component_size; - } - - *ppVertexElements = elements; + *ppVertexElements = state.elements; return size; } @@ -1282,35 +1388,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DW IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; IWineD3DPaletteImpl *object; HRESULT hr; - TRACE("(%p)->(%x, %p, %p, %p)\n", This, Flags, PalEnt, Palette, Parent); - /* Create the new object */ - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DPaletteImpl)); - if(!object) { - ERR("Out of memory when allocating memory for a IWineD3DPalette implementation\n"); + TRACE("iface %p, flags %#x, entries %p, palette %p, parent %p.\n", + iface, Flags, PalEnt, Palette, Parent); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate palette memory.\n"); return E_OUTOFMEMORY; } - object->lpVtbl = &IWineD3DPalette_Vtbl; - object->ref = 1; - object->Flags = Flags; - object->parent = Parent; - object->device = This; - object->palNumEntries = IWineD3DPaletteImpl_Size(Flags); - object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion)); - - if(!object->hpal) { - HeapFree( GetProcessHeap(), 0, object); - return E_OUTOFMEMORY; - } - - hr = IWineD3DPalette_SetEntries((IWineD3DPalette *) object, 0, 0, IWineD3DPaletteImpl_Size(Flags), PalEnt); - if(FAILED(hr)) { - IWineD3DPalette_Release((IWineD3DPalette *) object); + hr = wined3d_palette_init(object, This, Flags, PalEnt, Parent); + if (FAILED(hr)) + { + WARN("Failed to initialize palette, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); return hr; } - *Palette = (IWineD3DPalette *) object; + TRACE("Created palette %p.\n", object); + *Palette = (IWineD3DPalette *)object; return WINED3D_OK; } @@ -1429,6 +1527,30 @@ static void destroy_dummy_textures(IWineD3DDeviceImpl *device, const struct wine memset(device->dummyTextureName, 0, gl_info->limits.textures * sizeof(*device->dummyTextureName)); } +static HRESULT WINAPI IWineD3DDeviceImpl_AcquireFocusWindow(IWineD3DDevice *iface, HWND window) +{ + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface; + + if (!wined3d_register_window(window, device)) + { + ERR("Failed to register window %p.\n", window); + return E_FAIL; + } + + device->focus_window = window; + SetForegroundWindow(window); + + return WINED3D_OK; +} + +static void WINAPI IWineD3DDeviceImpl_ReleaseFocusWindow(IWineD3DDevice *iface) +{ + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface; + + if (device->focus_window) wined3d_unregister_window(device->focus_window); + device->focus_window = NULL; +} + static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) { @@ -1445,17 +1567,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, if(This->d3d_initialized) return WINED3DERR_INVALIDCALL; if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL; - if (!pPresentationParameters->Windowed) - { - This->focus_window = This->createParms.hFocusWindow; - if (!This->focus_window) This->focus_window = pPresentationParameters->hDeviceWindow; - if (!wined3d_register_window(This->focus_window, This)) - { - ERR("Failed to register window %p.\n", This->focus_window); - return E_FAIL; - } - } - TRACE("(%p) : Creating stateblock\n", This); /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */ hr = IWineD3DDevice_CreateStateBlock(iface, @@ -1471,7 +1582,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock); This->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IWineD3DSurface *) * gl_info->limits.buffers); + sizeof(*This->render_targets) * gl_info->limits.buffers); This->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * gl_info->limits.buffers); @@ -1509,8 +1620,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, } } - if (This->focus_window) SetFocus(This->focus_window); - /* Setup the implicit swapchain. This also initializes a context. */ TRACE("Creating implicit swapchain\n"); hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent, @@ -1529,21 +1638,22 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, } This->swapchains[0] = (IWineD3DSwapChain *) swapchain; - if(swapchain->backBuffer && swapchain->backBuffer[0]) { - TRACE("Setting rendertarget to %p\n", swapchain->backBuffer); - This->render_targets[0] = swapchain->backBuffer[0]; + if (swapchain->back_buffers && swapchain->back_buffers[0]) + { + TRACE("Setting rendertarget to %p.\n", swapchain->back_buffers); + This->render_targets[0] = swapchain->back_buffers[0]; } - else { - TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer); - This->render_targets[0] = swapchain->frontBuffer; + else + { + TRACE("Setting rendertarget to %p.\n", swapchain->front_buffer); + This->render_targets[0] = swapchain->front_buffer; } - IWineD3DSurface_AddRef(This->render_targets[0]); + IWineD3DSurface_AddRef((IWineD3DSurface *)This->render_targets[0]); /* Depth Stencil support */ - This->stencilBufferTarget = This->auto_depth_stencil_buffer; - if (NULL != This->stencilBufferTarget) { - IWineD3DSurface_AddRef(This->stencilBufferTarget); - } + This->depth_stencil = This->auto_depth_stencil; + if (This->depth_stencil) + IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil); hr = This->shader_backend->shader_alloc_private(iface); if(FAILED(hr)) { @@ -1566,7 +1676,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, /* Setup all the devices defaults */ IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock); - context = context_acquire(This, swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, swapchain->front_buffer); create_dummy_textures(This); @@ -1583,10 +1693,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, This->offscreenBuffer = GL_COLOR_ATTACHMENT0; break; - case ORM_PBUFFER: - This->offscreenBuffer = GL_BACK; - break; - case ORM_BACKBUFFER: { if (context_get_current()->aux_buffers > 0) @@ -1645,7 +1751,6 @@ err_out: if (This->shader_priv) { This->shader_backend->shader_free_private(iface); } - if (This->focus_window) wined3d_unregister_window(This->focus_window); return hr; } @@ -1702,7 +1807,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, /* I don't think that the interface guarantees that the device is destroyed from the same thread * it was created. Thus make sure a context is active for the glDelete* calls */ - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); gl_info = context->gl_info; if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface); @@ -1720,9 +1825,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, } } - /* Delete the pbuffer context if there is any */ - if(This->pbufferContext) context_destroy(This, This->pbufferContext); - /* Delete the mouse cursor texture */ if(This->cursorTexture) { ENTER_GL(); @@ -1781,26 +1883,33 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, This->shader_backend->shader_free_private(iface); /* Release the buffers (with sanity checks)*/ - TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); - if(This->stencilBufferTarget != NULL && (IWineD3DSurface_Release(This->stencilBufferTarget) >0)){ - if(This->auto_depth_stencil_buffer != This->stencilBufferTarget) - FIXME("(%p) Something's still holding the stencilBufferTarget\n",This); + if (This->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); + This->onscreen_depth_stencil = NULL; } - This->stencilBufferTarget = NULL; + + TRACE("Releasing the depth stencil buffer at %p\n", This->depth_stencil); + if (This->depth_stencil && IWineD3DSurface_Release((IWineD3DSurface *)This->depth_stencil)) + { + if (This->auto_depth_stencil != This->depth_stencil) + FIXME("(%p) Something is still holding the depth/stencil buffer.\n",This); + } + This->depth_stencil = NULL; TRACE("Releasing the render target at %p\n", This->render_targets[0]); - if(IWineD3DSurface_Release(This->render_targets[0]) >0){ - /* This check is a bit silly, it should be in swapchain_release FIXME("(%p) Something's still holding the renderTarget\n",This); */ - } + IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[0]); + TRACE("Setting rendertarget to NULL\n"); This->render_targets[0] = NULL; - if (This->auto_depth_stencil_buffer) { - if (IWineD3DSurface_Release(This->auto_depth_stencil_buffer) > 0) + if (This->auto_depth_stencil) + { + if (IWineD3DSurface_Release((IWineD3DSurface *)This->auto_depth_stencil)) { FIXME("(%p) Something's still holding the auto depth stencil buffer\n", This); } - This->auto_depth_stencil_buffer = NULL; + This->auto_depth_stencil = NULL; } context_release(context); @@ -1828,8 +1937,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, This->d3d_initialized = FALSE; - if (This->focus_window) wined3d_unregister_window(This->focus_window); - return WINED3D_OK; } @@ -1867,8 +1974,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, U const WINED3DDISPLAYMODE* pMode) { DEVMODEW devmode; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + const struct wined3d_format_desc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info); LONG ret; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(pMode->Format, &This->adapter->gl_info); RECT clip_rc; TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format)); @@ -2982,7 +3089,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI( TRACE("(iface %p, dstData %p, start %d, count %d)\n", iface, dstData, start, count); - if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= (signed int) 0) + if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= 0) return WINED3DERR_INVALIDCALL; memcpy(dstData, &This->stateBlock->vertexShaderConstantI[start * 4], cnt * sizeof(int) * 4); @@ -3469,9 +3576,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn /* We might access VBOs from this code, so hold the lock */ ENTER_GL(); - if (dest->resource.allocatedMemory == NULL) { - buffer_get_sysmem(dest); - } + if (!dest->resource.allocatedMemory) + buffer_get_sysmem(dest, gl_info); /* Get a pointer into the destination vbo(create one if none exists) and * write correct opengl data into it. It's cheap and allows us to run drawStridedFast @@ -3518,7 +3624,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn FIXME("Clipping is broken and disabled for now\n"); } } else doClip = FALSE; - dest_ptr = ((char *) buffer_get_sysmem(dest)) + dwDestIndex * get_flexible_vertex_size(DestFVF); + dest_ptr = ((char *)buffer_get_sysmem(dest, gl_info)) + dwDestIndex * get_flexible_vertex_size(DestFVF); IWineD3DDevice_GetTransform( (IWineD3DDevice *) This, WINED3DTS_VIEW, @@ -3794,6 +3900,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct wined3d_stream_info stream_info; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; BOOL vbo = FALSE, streamWasUP = This->stateBlock->streamIsUP; HRESULT hr; @@ -3805,7 +3912,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, } /* Need any context to write to the vbo. */ - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); + gl_info = context->gl_info; /* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP * control the streamIsUP flag, thus restore it afterwards. @@ -3832,7 +3940,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, { struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; e->buffer_object = 0; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); + e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, gl_info)); ENTER_GL(); GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); vb->buffer_object = 0; @@ -4218,7 +4326,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndScene(IWineD3DDevice *iface) return WINED3DERR_INVALIDCALL; } - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ wglFlush(); /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever @@ -4250,18 +4358,81 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Present(IWineD3DDevice *iface, return WINED3D_OK; } +static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const RECT *draw_rect, const RECT *clear_rect) +{ + /* partial draw rect */ + if (draw_rect->left || draw_rect->top + || draw_rect->right < target->currentDesc.Width + || draw_rect->bottom < target->currentDesc.Height) + return FALSE; + + /* partial clear rect */ + if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0 + || clear_rect->right < target->currentDesc.Width + || clear_rect->bottom < target->currentDesc.Height)) + return FALSE; + + return TRUE; +} + +static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *context, + DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect) +{ + RECT current_rect, r; + + if (ds->Flags & location) + SetRect(¤t_rect, 0, 0, + ds->ds_current_size.cx, + ds->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + IntersectRect(&r, draw_rect, ¤t_rect); + if (EqualRect(&r, draw_rect)) + { + /* current_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); + return; + } + + if (EqualRect(&r, ¤t_rect)) + { + /* draw_rect ⊇ current_rect, test if we're doing a full clear. */ + + if (!clear_rect) + { + /* Full clear, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + + IntersectRect(&r, draw_rect, clear_rect); + if (EqualRect(&r, draw_rect)) + { + /* clear_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + } + + /* Full load. */ + surface_load_ds_location(ds, context, location); + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); +} + /* Not called from the VTable (internal subroutine) */ -HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, - CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color, - float Z, DWORD Stencil) { +HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, + const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) +{ + const RECT *clear_rect = (Count > 0 && pRects) ? (const RECT *)pRects : NULL; + IWineD3DSurfaceImpl *depth_stencil = This->depth_stencil; GLbitfield glMask = 0; unsigned int i; - WINED3DRECT curRect; - RECT vp_rect; - const WINED3DVIEWPORT *vp = &This->stateBlock->viewport; UINT drawable_width, drawable_height; - IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget; struct wined3d_context *context; + RECT draw_rect; + + device_get_draw_rect(This, &draw_rect); /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true @@ -4272,132 +4443,119 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa * the drawable up to date. We have to check all settings that limit the clear area though. Do not bother * checking all this if the dest surface is in the drawable anyway. */ - if((Flags & WINED3DCLEAR_TARGET) && !(target->Flags & SFLAG_INDRAWABLE)) { - while(1) { - if(vp->X != 0 || vp->Y != 0 || - vp->Width < target->currentDesc.Width || vp->Height < target->currentDesc.Height) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && ( - This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 || - This->stateBlock->scissorRect.right < target->currentDesc.Width || - This->stateBlock->scissorRect.bottom < target->currentDesc.Height)) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - if(Count > 0 && pRects && ( - pRects[0].x1 > 0 || pRects[0].y1 > 0 || - pRects[0].x2 < target->currentDesc.Width || - pRects[0].y2 < target->currentDesc.Height)) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - break; - } + if (Flags & WINED3DCLEAR_TARGET && !(target->Flags & SFLAG_INDRAWABLE)) + { + if (!is_full_clear(target, &draw_rect, clear_rect)) + IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL); } - context = context_acquire(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR); + context = context_acquire(This, target); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping clear.\n"); + return WINED3D_OK; + } + + context_apply_clear_state(context, This, target, depth_stencil); target->get_drawable_size(context, &drawable_width, &drawable_height); ENTER_GL(); /* Only set the values up once, as they are not changing */ - if (Flags & WINED3DCLEAR_STENCIL) { + if (Flags & WINED3DCLEAR_STENCIL) + { + if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE]) + { + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE)); + } + glStencilMask(~0U); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); glClearStencil(Stencil); checkGLcall("glClearStencil"); glMask = glMask | GL_STENCIL_BUFFER_BIT; - glStencilMask(0xFFFFFFFF); } - if (Flags & WINED3DCLEAR_ZBUFFER) { + if (Flags & WINED3DCLEAR_ZBUFFER) + { DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; + + if (location == SFLAG_DS_ONSCREEN && depth_stencil != This->onscreen_depth_stencil) + device_switch_onscreen_ds(This, context, depth_stencil); + prepare_ds_clear(depth_stencil, context, location, &draw_rect, Count, clear_rect); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)depth_stencil, SFLAG_INDRAWABLE, TRUE); + glDepthMask(GL_TRUE); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); glClearDepth(Z); checkGLcall("glClearDepth"); glMask = glMask | GL_DEPTH_BUFFER_BIT; - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); - - if (vp->X != 0 || vp->Y != 0 || - vp->Width < depth_stencil->currentDesc.Width || vp->Height < depth_stencil->currentDesc.Height) { - surface_load_ds_location(This->stencilBufferTarget, context, location); - } - else if (This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && ( - This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 || - This->stateBlock->scissorRect.right < depth_stencil->currentDesc.Width || - This->stateBlock->scissorRect.bottom < depth_stencil->currentDesc.Height)) { - surface_load_ds_location(This->stencilBufferTarget, context, location); - } - else if (Count > 0 && pRects && ( - pRects[0].x1 > 0 || pRects[0].y1 > 0 || - pRects[0].x2 < depth_stencil->currentDesc.Width || - pRects[0].y2 < depth_stencil->currentDesc.Height)) { - surface_load_ds_location(This->stencilBufferTarget, context, location); - } } - if (Flags & WINED3DCLEAR_TARGET) { - TRACE("Clearing screen with glClear to color %x\n", Color); - glClearColor(D3DCOLOR_R(Color), - D3DCOLOR_G(Color), - D3DCOLOR_B(Color), - D3DCOLOR_A(Color)); - checkGLcall("glClearColor"); + if (Flags & WINED3DCLEAR_TARGET) + { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); - /* Clear ALL colors! */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3)); + glClearColor(D3DCOLOR_R(Color), D3DCOLOR_G(Color), D3DCOLOR_B(Color), D3DCOLOR_A(Color)); + checkGLcall("glClearColor"); glMask = glMask | GL_COLOR_BUFFER_BIT; } - vp_rect.left = vp->X; - vp_rect.top = vp->Y; - vp_rect.right = vp->X + vp->Width; - vp_rect.bottom = vp->Y + vp->Height; - if (!(Count > 0 && pRects)) { - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) { - IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect); - } + if (!clear_rect) + { if (context->render_offscreen) { - glScissor(vp_rect.left, vp_rect.top, - vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top); - } else { - glScissor(vp_rect.left, drawable_height - vp_rect.bottom, - vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top); + glScissor(draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); + } + else + { + glScissor(draw_rect.left, drawable_height - draw_rect.bottom, + draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); } checkGLcall("glScissor"); glClear(glMask); checkGLcall("glClear"); - } else { - /* Now process each rect in turn */ - for (i = 0; i < Count; i++) { + } + else + { + RECT current_rect; + + /* Now process each rect in turn. */ + for (i = 0; i < Count; ++i) + { /* Note gl uses lower left, width/height */ - IntersectRect((RECT *)&curRect, &vp_rect, (const RECT *)&pRects[i]); - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) { - IntersectRect((RECT *) &curRect, (RECT *) &curRect, &This->stateBlock->scissorRect); - } - TRACE("(%p) Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d\n", This, - pRects[i].x1, pRects[i].y1, pRects[i].x2, pRects[i].y2, - curRect.x1, (target->currentDesc.Height - curRect.y2), - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); + IntersectRect(¤t_rect, &draw_rect, &clear_rect[i]); + + TRACE("clear_rect[%u] %s, current_rect %s.\n", i, + wine_dbgstr_rect(&clear_rect[i]), + wine_dbgstr_rect(¤t_rect)); /* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently. * The rectangle is not cleared, no error is returned, but further rectanlges are - * still cleared if they are valid - */ - if(curRect.x1 > curRect.x2 || curRect.y1 > curRect.y2) { - TRACE("Rectangle with negative dimensions, ignoring\n"); + * still cleared if they are valid. */ + if (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom) + { + TRACE("Rectangle with negative dimensions, ignoring.\n"); continue; } if (context->render_offscreen) { - glScissor(curRect.x1, curRect.y1, - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); - } else { - glScissor(curRect.x1, drawable_height - curRect.y2, - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); + glScissor(current_rect.left, current_rect.top, + current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); + } + else + { + glScissor(current_rect.left, drawable_height - current_rect.bottom, + current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); } checkGLcall("glScissor"); @@ -4406,52 +4564,33 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa } } - /* Restore the old values (why..?) */ - if (Flags & WINED3DCLEAR_STENCIL) { - glStencilMask(This->stateBlock->renderState[WINED3DRS_STENCILWRITEMASK]); - } - if (Flags & WINED3DCLEAR_TARGET) { - DWORD mask = This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE]; - glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); - - /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists, - * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it - */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); - } - if (Flags & WINED3DCLEAR_ZBUFFER) { - /* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */ - DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; - surface_modify_ds_location(This->stencilBufferTarget, location); - } - LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN) + && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target)) + wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, CONST WINED3DRECT* pRects, - DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) { +static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, + const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)This->render_targets[0]; TRACE("(%p) Count (%d), pRects (%p), Flags (%x), Color (0x%08x), Z (%f), Stencil (%d)\n", This, Count, pRects, Flags, Color, Z, Stencil); - if(Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && This->stencilBufferTarget == NULL) { + if (Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && !This->depth_stencil) + { WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); /* TODO: What about depth stencil buffers without stencil bits? */ return WINED3DERR_INVALIDCALL; } - return IWineD3DDeviceImpl_ClearSurface(This, target, Count, pRects, Flags, Color, Z, Stencil); + return IWineD3DDeviceImpl_ClearSurface(This, This->render_targets[0], Count, pRects, Flags, Color, Z, Stencil); } /***** @@ -5083,71 +5222,58 @@ static float WINAPI IWineD3DDeviceImpl_GetNPatchMode(IWineD3DDevice *iface) return 0.0f; } -static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, IWineD3DSurface *pSourceSurface, CONST RECT* pSourceRect, IWineD3DSurface *pDestinationSurface, CONST POINT* pDestPoint) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - /** TODO: remove casts to IWineD3DSurfaceImpl - * NOTE: move code to surface to accomplish this - ****************************************/ - IWineD3DSurfaceImpl *pSrcSurface = (IWineD3DSurfaceImpl *)pSourceSurface; - IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)pDestinationSurface; - int srcWidth, srcHeight; - unsigned int srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, destSurfaceHeight; - WINED3DFORMAT destFormat, srcFormat; - UINT destSize; - int srcLeft, destLeft, destTop; - WINED3DPOOL srcPool, destPool; - int offset = 0; - int rowoffset = 0; /* how many bytes to add onto the end of a row to wraparound to the beginning of the next */ - const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc; - GLenum dummy; - DWORD sampler; - int bpp; - CONVERT_TYPES convert = NO_CONVERSION; +static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, + IWineD3DSurface *src_surface, const RECT *src_rect, + IWineD3DSurface *dst_surface, const POINT *dst_point) +{ + IWineD3DSurfaceImpl *src_impl = (IWineD3DSurfaceImpl *)src_surface; + IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)dst_surface; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + const struct wined3d_format_desc *src_format; + const struct wined3d_format_desc *dst_format; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; + const unsigned char *data; + UINT update_w, update_h; + CONVERT_TYPES convert; + UINT src_w, src_h; + UINT dst_x, dst_y; + DWORD sampler; + struct wined3d_format_desc desc; - WINED3DSURFACE_DESC winedesc; + TRACE("iface %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n", + iface, src_surface, wine_dbgstr_rect(src_rect), + dst_surface, wine_dbgstr_point(dst_point)); - TRACE("(%p) : Source (%p) Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint); - - IWineD3DSurface_GetDesc(pSourceSurface, &winedesc); - srcSurfaceWidth = winedesc.width; - srcSurfaceHeight = winedesc.height; - srcPool = winedesc.pool; - srcFormat = winedesc.format; - - IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc); - destSurfaceWidth = winedesc.width; - destSurfaceHeight = winedesc.height; - destPool = winedesc.pool; - destFormat = winedesc.format; - destSize = winedesc.size; - - if(srcPool != WINED3DPOOL_SYSTEMMEM || destPool != WINED3DPOOL_DEFAULT){ - WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface); + if (src_impl->resource.pool != WINED3DPOOL_SYSTEMMEM || dst_impl->resource.pool != WINED3DPOOL_DEFAULT) + { + WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", + src_surface, dst_surface); return WINED3DERR_INVALIDCALL; } - /* This call loads the opengl surface directly, instead of copying the surface to the - * destination's sysmem copy. If surface conversion is needed, use BltFast instead to - * copy in sysmem and use regular surface loading. - */ - d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy, &dummy, &dummy, &convert, &bpp, FALSE); - if(convert != NO_CONVERSION) { - return IWineD3DSurface_BltFast(pDestinationSurface, - pDestPoint ? pDestPoint->x : 0, - pDestPoint ? pDestPoint->y : 0, - pSourceSurface, pSourceRect, 0); + src_format = src_impl->resource.format_desc; + dst_format = dst_impl->resource.format_desc; + + if (src_format->format != dst_format->format) + { + WARN("Source and destination surfaces should have the same format.\n"); + return WINED3DERR_INVALIDCALL; } - if (destFormat == WINED3DFMT_UNKNOWN) { - TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", This); - IWineD3DSurface_SetFormat(pDestinationSurface, srcFormat); + dst_x = dst_point ? dst_point->x : 0; + dst_y = dst_point ? dst_point->y : 0; - /* Get the update surface description */ - IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc); - } + /* This call loads the OpenGL surface directly, instead of copying the + * surface to the destination's sysmem copy. If surface conversion is + * needed, use BltFast instead to copy in sysmem and use regular surface + * loading. */ + d3dfmt_get_conv(dst_impl, FALSE, TRUE, &desc, &convert); + if (convert != NO_CONVERSION || desc.convert) + return IWineD3DSurface_BltFast(dst_surface, dst_x, dst_y, src_surface, src_rect, 0); - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); + gl_info = context->gl_info; ENTER_GL(); GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB)); @@ -5155,92 +5281,79 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, LEAVE_GL(); /* Make sure the surface is loaded and up to date */ - surface_internal_preload(pDestinationSurface, SRGB_RGB); - IWineD3DSurface_BindTexture(pDestinationSurface, FALSE); + surface_internal_preload(dst_impl, SRGB_RGB); + IWineD3DSurface_BindTexture(dst_surface, FALSE); - src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc; - dst_format_desc = dst_impl->resource.format_desc; + src_w = src_impl->currentDesc.Width; + src_h = src_impl->currentDesc.Height; + update_w = src_rect ? src_rect->right - src_rect->left : src_w; + update_h = src_rect ? src_rect->bottom - src_rect->top : src_h; - /* this needs to be done in lines if the sourceRect != the sourceWidth */ - srcWidth = pSourceRect ? pSourceRect->right - pSourceRect->left : srcSurfaceWidth; - srcHeight = pSourceRect ? pSourceRect->bottom - pSourceRect->top : srcSurfaceHeight; - srcLeft = pSourceRect ? pSourceRect->left : 0; - destLeft = pDestPoint ? pDestPoint->x : 0; - destTop = pDestPoint ? pDestPoint->y : 0; - - - /* This function doesn't support compressed textures - the pitch is just bytesPerPixel * width */ - if(srcWidth != srcSurfaceWidth || srcLeft ){ - rowoffset = srcSurfaceWidth * src_format_desc->byte_count; - offset += srcLeft * src_format_desc->byte_count; - /* TODO: do we ever get 3bpp?, would a shift and an add be quicker than a mul (well maybe a cycle or two) */ - } - /* TODO DXT formats */ - - if(pSourceRect != NULL && pSourceRect->top != 0){ - offset += pSourceRect->top * srcSurfaceWidth * src_format_desc->byte_count; - } - TRACE("(%p) glTexSubImage2D, level %d, left %d, top %d, width %d, height %d, fmt %#x, type %#x, memory %p+%#x\n", - This, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat, - dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset); - - /* Sanity check */ - if (IWineD3DSurface_GetData(pSourceSurface) == NULL) { - - /* need to lock the surface to get the data */ - FIXME("Surfaces has no allocated memory, but should be an in memory only surface\n"); - } + data = IWineD3DSurface_GetData(src_surface); + if (!data) ERR("Source surface has no allocated memory, but should be a sysmem surface.\n"); ENTER_GL(); - /* TODO: Cube and volume support */ - if(rowoffset != 0){ - /* not a whole row so we have to do it a line at a time */ - int j; + if (dst_format->Flags & WINED3DFMT_FLAG_COMPRESSED) + { + UINT row_length = (update_w / src_format->block_width) * src_format->block_byte_count; + UINT row_count = update_h / src_format->block_height; + UINT src_pitch = IWineD3DSurface_GetPitch(src_surface); - /* hopefully using pointer addition will be quicker than using a point + j * rowoffset */ - const unsigned char* data =((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset; - - for (j = destTop; j < (srcHeight + destTop); ++j) + if (src_rect) { - glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j, - srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data); - data += rowoffset; + data += (src_rect->top / src_format->block_height) * src_pitch; + data += (src_rect->left / src_format->block_width) * src_format->block_byte_count; } - } else { /* Full width, so just write out the whole texture */ - const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset; + TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, " + "format %#x, image_size %#x, data %p.\n", dst_impl->texture_target, dst_impl->texture_level, + dst_x, dst_y, update_w, update_h, dst_format->glFormat, row_count * row_length, data); - if (dst_format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED) + if (row_length == src_pitch) { - if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth) - { - /* FIXME: The easy way to do this is to lock the destination, and copy the bits across. */ - FIXME("Updating part of a compressed texture is not supported.\n"); - } - if (destFormat != srcFormat) - { - FIXME("Updating mixed format compressed textures is not supported.\n"); - } - else - { - GL_EXTCALL(glCompressedTexImage2DARB(dst_impl->texture_target, dst_impl->texture_level, - dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data)); - } + GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level, + dst_x, dst_y, update_w, update_h, dst_format->glInternal, row_count * row_length, data)); } else { - glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop, - srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data); + UINT row, y; + + /* glCompressedTexSubImage2DARB() ignores pixel store state, so we + * can't use the unpack row length like below. */ + for (row = 0, y = dst_y; row < row_count; ++row) + { + GL_EXTCALL(glCompressedTexSubImage2DARB(dst_impl->texture_target, dst_impl->texture_level, + dst_x, y, update_w, src_format->block_height, dst_format->glInternal, row_length, data)); + y += src_format->block_height; + data += src_pitch; + } } - } - checkGLcall("glTexSubImage2D"); + checkGLcall("glCompressedTexSubImage2DARB"); + } + else + { + if (src_rect) + { + data += src_rect->top * src_w * src_format->byte_count; + data += src_rect->left * src_format->byte_count; + } + + TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, data %p.\n", + dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y, + update_w, update_h, dst_format->glFormat, dst_format->glType, data); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, src_w); + glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, dst_x, dst_y, + update_w, update_h, dst_format->glFormat, dst_format->glType, data); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + checkGLcall("glTexSubImage2D"); + } LEAVE_GL(); context_release(context); - IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE); + IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INTEXTURE, TRUE); sampler = This->rev_tex_unit_map[0]; if (sampler != WINED3D_UNMAPPED_STAGE) { @@ -5370,68 +5483,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DeletePatch(IWineD3DDevice *iface, UINT return WINED3DERR_INVALIDCALL; } -static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) { - HRESULT hr; - IWineD3DSwapChain *swapchain; - - hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain); - if (SUCCEEDED(hr)) { - IWineD3DSwapChain_Release((IUnknown *)swapchain); - return swapchain; - } - - return NULL; -} - -static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, +static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface, const WINED3DRECT *rect, const float color[4]) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; struct wined3d_context *context; - if (rect) IWineD3DSurface_LoadLocation(surface, SFLAG_INDRAWABLE, NULL); - IWineD3DSurface_ModifyLocation(surface, SFLAG_INDRAWABLE, TRUE); + if (rect) IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INDRAWABLE, TRUE); - if (!surface_is_offscreen(surface)) + context = context_acquire(This, surface); + context_apply_clear_state(context, This, surface, NULL); + + ENTER_GL(); + + if (rect) { - TRACE("Surface %p is onscreen\n", surface); - - context = context_acquire(This, surface, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - context_set_draw_buffer(context, surface_get_gl_buffer(surface)); + if (surface_is_offscreen(surface)) + glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1); + else + glScissor(rect->x1, surface->currentDesc.Height - rect->y2, + rect->x2 - rect->x1, rect->y2 - rect->y1); + checkGLcall("glScissor"); } else { - TRACE("Surface %p is offscreen\n", surface); - - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, surface); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); - } - - if (rect) { - glEnable(GL_SCISSOR_TEST); - if(surface_is_offscreen(surface)) { - glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1); - } else { - glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2, - rect->x2 - rect->x1, rect->y2 - rect->y1); - } - checkGLcall("glScissor"); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SCISSORRECT); - } else { glDisable(GL_SCISSOR_TEST); } - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); - - glDisable(GL_BLEND); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE)); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3)); glClearColor(color[0], color[1], color[2], color[3]); glClear(GL_COLOR_BUFFER_BIT); @@ -5439,119 +5523,11 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); } -static inline DWORD argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) { - unsigned int r, g, b, a; - DWORD ret; - - if (destfmt == WINED3DFMT_B8G8R8A8_UNORM - || destfmt == WINED3DFMT_B8G8R8X8_UNORM - || destfmt == WINED3DFMT_B8G8R8_UNORM) - return color; - - TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt)); - - a = (color & 0xff000000) >> 24; - r = (color & 0x00ff0000) >> 16; - g = (color & 0x0000ff00) >> 8; - b = (color & 0x000000ff) >> 0; - - switch(destfmt) - { - case WINED3DFMT_B5G6R5_UNORM: - if(r == 0xff && g == 0xff && b == 0xff) return 0xffff; - r = (r * 32) / 256; - g = (g * 64) / 256; - b = (b * 32) / 256; - ret = r << 11; - ret |= g << 5; - ret |= b; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_B5G5R5X1_UNORM: - case WINED3DFMT_B5G5R5A1_UNORM: - a = (a * 2) / 256; - r = (r * 32) / 256; - g = (g * 32) / 256; - b = (b * 32) / 256; - ret = a << 15; - ret |= r << 10; - ret |= g << 5; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_A8_UNORM: - TRACE("Returning %08x\n", a); - return a; - - case WINED3DFMT_B4G4R4X4_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - a = (a * 16) / 256; - r = (r * 16) / 256; - g = (g * 16) / 256; - b = (b * 16) / 256; - ret = a << 12; - ret |= r << 8; - ret |= g << 4; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_B2G3R3_UNORM: - r = (r * 8) / 256; - g = (g * 8) / 256; - b = (b * 4) / 256; - ret = r << 5; - ret |= g << 2; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_R8G8B8X8_UNORM: - case WINED3DFMT_R8G8B8A8_UNORM: - ret = a << 24; - ret |= b << 16; - ret |= g << 8; - ret |= r << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_B10G10R10A2_UNORM: - a = (a * 4) / 256; - r = (r * 1024) / 256; - g = (g * 1024) / 256; - b = (b * 1024) / 256; - ret = a << 30; - ret |= r << 20; - ret |= g << 10; - ret |= b << 0; - TRACE("Returning %08x\n", ret); - return ret; - - case WINED3DFMT_R10G10B10A2_UNORM: - a = (a * 4) / 256; - r = (r * 1024) / 256; - g = (g * 1024) / 256; - b = (b * 1024) / 256; - ret = a << 30; - ret |= b << 20; - ret |= g << 10; - ret |= r << 0; - TRACE("Returning %08x\n", ret); - return ret; - - default: - FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt)); - return 0; - } -} - static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD3DSurface *pSurface, const WINED3DRECT *pRect, WINED3DCOLOR color) { @@ -5567,13 +5543,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { const float c[4] = {D3DCOLOR_R(color), D3DCOLOR_G(color), D3DCOLOR_B(color), D3DCOLOR_A(color)}; - color_fill_fbo(iface, pSurface, pRect, c); + color_fill_fbo(iface, surface, pRect, c); return WINED3D_OK; } else { /* Just forward this to the DirectDraw blitting engine */ memset(&BltFx, 0, sizeof(BltFx)); BltFx.dwSize = sizeof(BltFx); - BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format); + BltFx.u5.dwFillColor = color_convert_argb_to_fmt(color, surface->resource.format_desc->format); return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); } @@ -5583,7 +5559,7 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac IWineD3DRendertargetView *rendertarget_view, const float color[4]) { IWineD3DResource *resource; - IWineD3DSurface *surface; + IWineD3DSurfaceImpl *surface; HRESULT hr; hr = IWineD3DRendertargetView_GetResource(rendertarget_view, &resource); @@ -5600,7 +5576,7 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac return; } - surface = (IWineD3DSurface *)resource; + surface = (IWineD3DSurfaceImpl *)resource; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { @@ -5621,8 +5597,9 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac /* Just forward this to the DirectDraw blitting engine */ memset(&BltFx, 0, sizeof(BltFx)); BltFx.dwSize = sizeof(BltFx); - BltFx.u5.dwFillColor = argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format); - hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); + BltFx.u5.dwFillColor = color_convert_argb_to_fmt(c, surface->resource.format_desc->format); + hr = IWineD3DSurface_Blt((IWineD3DSurface *)surface, NULL, NULL, NULL, + WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); if (FAILED(hr)) { ERR("Blt failed, hr %#x\n", hr); @@ -5643,7 +5620,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice* iface return WINED3DERR_INVALIDCALL; } - *ppRenderTarget = This->render_targets[RenderTargetIndex]; + *ppRenderTarget = (IWineD3DSurface *)This->render_targets[RenderTargetIndex]; TRACE("(%p) : RenderTarget %d Index returning %p\n", This, RenderTargetIndex, *ppRenderTarget); /* Note inc ref on returned surface */ if(*ppRenderTarget != NULL) @@ -5652,110 +5629,103 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice* iface } static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *iface, - IWineD3DSurface *Front, IWineD3DSurface *Back) + IWineD3DSurface *front, IWineD3DSurface *back) { - IWineD3DSurfaceImpl *FrontImpl = (IWineD3DSurfaceImpl *) Front; - IWineD3DSurfaceImpl *BackImpl = (IWineD3DSurfaceImpl *) Back; - IWineD3DSwapChainImpl *Swapchain; + IWineD3DSurfaceImpl *front_impl = (IWineD3DSurfaceImpl *)front; + IWineD3DSurfaceImpl *back_impl = (IWineD3DSurfaceImpl *)back; + IWineD3DSwapChainImpl *swapchain; HRESULT hr; - TRACE("iface %p, front %p, back %p.\n", iface, Front, Back); + TRACE("iface %p, front %p, back %p.\n", iface, front, back); - hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &Swapchain); - if(hr != WINED3D_OK) { - ERR("Can't get the swapchain\n"); + if (FAILED(hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **)&swapchain))) + { + ERR("Failed to get the swapchain, hr %#x.\n", hr); return hr; } - /* Make sure to release the swapchain */ - IWineD3DSwapChain_Release((IWineD3DSwapChain *) Swapchain); - - if(FrontImpl && !(FrontImpl->resource.usage & WINED3DUSAGE_RENDERTARGET) ) { - ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n"); - return WINED3DERR_INVALIDCALL; - } - else if(BackImpl && !(BackImpl->resource.usage & WINED3DUSAGE_RENDERTARGET)) { - ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage\n"); + if (front_impl && !(front_impl->resource.usage & WINED3DUSAGE_RENDERTARGET)) + { + ERR("Trying to set a front buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n"); + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); return WINED3DERR_INVALIDCALL; } - if(Swapchain->frontBuffer != Front) { - TRACE("Changing the front buffer from %p to %p\n", Swapchain->frontBuffer, Front); - - if(Swapchain->frontBuffer) + if (back_impl) + { + if (!(back_impl->resource.usage & WINED3DUSAGE_RENDERTARGET)) { - IWineD3DSurface_SetContainer(Swapchain->frontBuffer, NULL); - ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN; + ERR("Trying to set a back buffer which doesn't have WINED3DUSAGE_RENDERTARGET usage.\n"); + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); + return WINED3DERR_INVALIDCALL; } - Swapchain->frontBuffer = Front; - if(Swapchain->frontBuffer) { - IWineD3DSurface_SetContainer(Swapchain->frontBuffer, (IWineD3DBase *) Swapchain); - ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; - } - } - - if(Back && !Swapchain->backBuffer) { - /* We need memory for the back buffer array - only one back buffer this way */ - Swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *)); - if(!Swapchain->backBuffer) { - ERR("Out of memory\n"); - return E_OUTOFMEMORY; - } - } - - if(Swapchain->backBuffer[0] != Back) { - TRACE("Changing the back buffer from %p to %p\n", Swapchain->backBuffer, Back); - - /* What to do about the context here in the case of multithreading? Not sure. - * This function is called by IDirect3D7::CreateDevice so in theory its initialization code - */ - WARN("No active context?\n"); - - ENTER_GL(); - if(!Swapchain->backBuffer[0]) { - /* GL was told to draw to the front buffer at creation, - * undo that - */ - glDrawBuffer(GL_BACK); - checkGLcall("glDrawBuffer(GL_BACK)"); - /* Set the backbuffer count to 1 because other code uses it to fing the back buffers */ - Swapchain->presentParms.BackBufferCount = 1; - } else if (!Back) { - /* That makes problems - disable for now */ - /* glDrawBuffer(GL_FRONT); */ - checkGLcall("glDrawBuffer(GL_FRONT)"); - /* We have lost our back buffer, set this to 0 to avoid confusing other code */ - Swapchain->presentParms.BackBufferCount = 0; - } - LEAVE_GL(); - - if(Swapchain->backBuffer[0]) + if (!swapchain->back_buffers) { - IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], NULL); - ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN; + swapchain->back_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*swapchain->back_buffers)); + if (!swapchain->back_buffers) + { + ERR("Failed to allocate back buffer array memory.\n"); + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); + return E_OUTOFMEMORY; + } } - Swapchain->backBuffer[0] = Back; - - if(Swapchain->backBuffer[0]) { - IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain); - ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags |= SFLAG_SWAPCHAIN; - Swapchain->presentParms.BackBufferWidth = BackImpl->currentDesc.Width; - Swapchain->presentParms.BackBufferHeight = BackImpl->currentDesc.Height; - Swapchain->presentParms.BackBufferFormat = BackImpl->resource.format_desc->format; - } else { - HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer); - Swapchain->backBuffer = NULL; - } - } + if (swapchain->front_buffer != front_impl) + { + TRACE("Changing the front buffer from %p to %p.\n", swapchain->front_buffer, front_impl); + + if (swapchain->front_buffer) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, NULL); + swapchain->front_buffer->Flags &= ~SFLAG_SWAPCHAIN; + } + swapchain->front_buffer = front_impl; + + if (front) + { + IWineD3DSurface_SetContainer(front, (IWineD3DBase *)swapchain); + front_impl->Flags |= SFLAG_SWAPCHAIN; + } + } + + if (swapchain->back_buffers[0] != back_impl) + { + TRACE("Changing the back buffer from %p to %p.\n", swapchain->back_buffers[0], back_impl); + + if (swapchain->back_buffers[0]) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[0], NULL); + swapchain->back_buffers[0]->Flags &= ~SFLAG_SWAPCHAIN; + } + swapchain->back_buffers[0] = back_impl; + + if (back) + { + swapchain->presentParms.BackBufferWidth = back_impl->currentDesc.Width; + swapchain->presentParms.BackBufferHeight = back_impl->currentDesc.Height; + swapchain->presentParms.BackBufferFormat = back_impl->resource.format_desc->format; + swapchain->presentParms.BackBufferCount = 1; + + IWineD3DSurface_SetContainer(back, (IWineD3DBase *)swapchain); + back_impl->Flags |= SFLAG_SWAPCHAIN; + } + else + { + swapchain->presentParms.BackBufferCount = 0; + HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); + swapchain->back_buffers = NULL; + } + } + + IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain); return WINED3D_OK; } static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice* iface, IWineD3DSurface **ppZStencilSurface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *ppZStencilSurface = This->stencilBufferTarget; + *ppZStencilSurface = (IWineD3DSurface *)This->depth_stencil; TRACE("(%p) : zStencilSurface returning %p\n", This, *ppZStencilSurface); if(*ppZStencilSurface != NULL) { @@ -5767,21 +5737,21 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice } } -void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect, - IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) +void stretch_rect_fbo(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect_in, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */ - IWineD3DSwapChain *src_swapchain, *dst_swapchain; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; GLenum gl_filter; - POINT offset = {0, 0}; + RECT src_rect, dst_rect; - TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n", - This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter, flip); - TRACE("src_rect [%u, %u]->[%u, %u]\n", src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2); - TRACE("dst_rect [%u, %u]->[%u, %u]\n", dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2); + TRACE("device %p, src_surface %p, src_rect_in %s, dst_surface %p, dst_rect_in %s, filter %s (0x%08x).\n", + device, src_surface, wine_dbgstr_rect(src_rect_in), dst_surface, + wine_dbgstr_rect(dst_rect_in), debug_d3dtexturefiltertype(filter), filter); + + src_rect = *src_rect_in; + dst_rect = *dst_rect_in; switch (filter) { case WINED3DTEXF_LINEAR: @@ -5799,16 +5769,19 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED /* Make sure the drawables are up-to-date. Note that loading the * destination surface isn't strictly required if we overwrite the * entire surface. */ - IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL); - IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)src_surface, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, NULL); - /* Attach src surface to src fbo */ - src_swapchain = get_swapchain(src_surface); - dst_swapchain = get_swapchain(dst_surface); + if (!surface_is_offscreen(src_surface)) context = context_acquire(device, src_surface); + else if (!surface_is_offscreen(dst_surface)) context = context_acquire(device, dst_surface); + else context = context_acquire(device, NULL); - if (src_swapchain) context = context_acquire(This, src_surface, CTXUSAGE_RESOURCELOAD); - else if (dst_swapchain) context = context_acquire(This, dst_surface, CTXUSAGE_RESOURCELOAD); - else context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping blit.\n"); + return; + } gl_info = context->gl_info; @@ -5818,19 +5791,11 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED TRACE("Source surface %p is onscreen\n", src_surface); - if(buffer == GL_FRONT) { - RECT windowsize; - UINT h; - ClientToScreen(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &offset); - GetClientRect(((IWineD3DSwapChainImpl *)src_swapchain)->win_handle, &windowsize); - h = windowsize.bottom - windowsize.top; - src_rect->x1 -= offset.x; src_rect->x2 -=offset.x; - src_rect->y1 = offset.y + h - src_rect->y1; - src_rect->y2 = offset.y + h - src_rect->y2; - } else { - src_rect->y1 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y1; - src_rect->y2 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y2; - } + if (buffer == GL_FRONT) + surface_translate_frontbuffer_coords(src_surface, context->win_handle, &src_rect); + + src_rect.top = src_surface->currentDesc.Height - src_rect.top; + src_rect.bottom = src_surface->currentDesc.Height - src_rect.bottom; ENTER_GL(); context_bind_fbo(context, GL_READ_FRAMEBUFFER, NULL); @@ -5839,11 +5804,9 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED } else { TRACE("Source surface %p is offscreen\n", src_surface); ENTER_GL(); - context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo); - context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, src_surface); + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL); glReadBuffer(GL_COLOR_ATTACHMENT0); checkGLcall("glReadBuffer()"); - context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE); } LEAVE_GL(); @@ -5854,20 +5817,11 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED TRACE("Destination surface %p is onscreen\n", dst_surface); - if(buffer == GL_FRONT) { - RECT windowsize; - UINT h; - ClientToScreen(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &offset); - GetClientRect(((IWineD3DSwapChainImpl *)dst_swapchain)->win_handle, &windowsize); - h = windowsize.bottom - windowsize.top; - dst_rect->x1 -= offset.x; dst_rect->x2 -=offset.x; - dst_rect->y1 = offset.y + h - dst_rect->y1; - dst_rect->y2 = offset.y + h - dst_rect->y2; - } else { - /* Screen coords = window coords, surface height = window height */ - dst_rect->y1 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y1; - dst_rect->y2 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y2; - } + if (buffer == GL_FRONT) + surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); + + dst_rect.top = dst_surface->currentDesc.Height - dst_rect.top; + dst_rect.bottom = dst_surface->currentDesc.Height - dst_rect.bottom; ENTER_GL(); context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL); @@ -5878,31 +5832,23 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED TRACE("Destination surface %p is offscreen\n", dst_surface); ENTER_GL(); - context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, dst_surface); + context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL); context_set_draw_buffer(context, GL_COLOR_ATTACHMENT0); - context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE); } glDisable(GL_SCISSOR_TEST); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE)); - if (flip) { - gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2, - dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter); - checkGLcall("glBlitFramebuffer()"); - } else { - gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2, - dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter); - checkGLcall("glBlitFramebuffer()"); - } + gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, + dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter); + checkGLcall("glBlitFramebuffer()"); LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); - IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); } static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget, @@ -5932,13 +5878,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, } /* If we are trying to set what we already have, don't bother */ - if (pRenderTarget == This->render_targets[RenderTargetIndex]) { + if (pRenderTarget == (IWineD3DSurface *)This->render_targets[RenderTargetIndex]) + { TRACE("Trying to do a NOP SetRenderTarget operation\n"); return WINED3D_OK; } - if(pRenderTarget) IWineD3DSurface_AddRef(pRenderTarget); - if(This->render_targets[RenderTargetIndex]) IWineD3DSurface_Release(This->render_targets[RenderTargetIndex]); - This->render_targets[RenderTargetIndex] = pRenderTarget; + if (pRenderTarget) + IWineD3DSurface_AddRef(pRenderTarget); + if (This->render_targets[RenderTargetIndex]) + IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[RenderTargetIndex]); + This->render_targets[RenderTargetIndex] = (IWineD3DSurfaceImpl *)pRenderTarget; /* Render target 0 is special */ if(RenderTargetIndex == 0 && set_viewport) { @@ -5946,8 +5895,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, * Tests show that stateblock recording is ignored, the change goes * directly into the primary stateblock. */ - This->stateBlock->viewport.Height = ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height; - This->stateBlock->viewport.Width = ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Width; + This->stateBlock->viewport.Height = This->render_targets[0]->currentDesc.Height; + This->stateBlock->viewport.Width = This->render_targets[0]->currentDesc.Width; This->stateBlock->viewport.X = 0; This->stateBlock->viewport.Y = 0; This->stateBlock->viewport.MaxZ = 1.0f; @@ -5965,49 +5914,46 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *iface, IWineD3DSurface *pNewZStencil) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - HRESULT hr = WINED3D_OK; - IWineD3DSurface *tmp; + IWineD3DSurfaceImpl *tmp; - TRACE("(%p) Swapping z-buffer. Old = %p, new = %p\n",This, This->stencilBufferTarget, pNewZStencil); + TRACE("device %p, depth_stencil %p, old depth_stencil %p.\n", This, pNewZStencil, This->depth_stencil); - if (pNewZStencil == This->stencilBufferTarget) { - TRACE("Trying to do a NOP SetRenderTarget operation\n"); - } else { - /** OpenGL doesn't support 'sharing' of the stencilBuffer so we may incur an extra memory overhead - * depending on the renter target implementation being used. - * A shared context implementation will share all buffers between all rendertargets (including swapchains), - * implementations that use separate pbuffers for different swapchains or rendertargets will have to duplicate the - * stencil buffer and incur an extra memory overhead - ******************************************************/ + if (This->depth_stencil == (IWineD3DSurfaceImpl *)pNewZStencil) + { + TRACE("Trying to do a NOP SetRenderTarget operation.\n"); + return WINED3D_OK; + } - if (This->stencilBufferTarget) { - if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED); - } else { - struct wined3d_context *context = context_acquire(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD); - surface_load_ds_location(This->stencilBufferTarget, context, SFLAG_DS_OFFSCREEN); - surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); - context_release(context); + if (This->depth_stencil) + { + if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL + || This->depth_stencil->Flags & SFLAG_DISCARD) + { + surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED, + This->depth_stencil->currentDesc.Width, + This->depth_stencil->currentDesc.Height); + if (This->depth_stencil == This->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); + This->onscreen_depth_stencil = NULL; } } - - tmp = This->stencilBufferTarget; - This->stencilBufferTarget = pNewZStencil; - /* should we be calling the parent or the wined3d surface? */ - if (NULL != This->stencilBufferTarget) IWineD3DSurface_AddRef(This->stencilBufferTarget); - if (NULL != tmp) IWineD3DSurface_Release(tmp); - hr = WINED3D_OK; - - if((!tmp && pNewZStencil) || (!pNewZStencil && tmp)) { - /* Swapping NULL / non NULL depth stencil affects the depth and tests */ - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); - } } - return hr; + tmp = This->depth_stencil; + This->depth_stencil = (IWineD3DSurfaceImpl *)pNewZStencil; + if (This->depth_stencil) IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil); + if (tmp) IWineD3DSurface_Release((IWineD3DSurface *)tmp); + + if ((!tmp && pNewZStencil) || (!pNewZStencil && tmp)) + { + /* Swapping NULL / non NULL depth stencil affects the depth and tests */ + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); + } + + return WINED3D_OK; } static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* iface, UINT XHotSpot, @@ -6020,8 +5966,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot); /* some basic validation checks */ - if(This->cursorTexture) { - struct wined3d_context *context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + if (This->cursorTexture) + { + struct wined3d_context *context = context_acquire(This, NULL); ENTER_GL(); glDeleteTextures(1, &This->cursorTexture); LEAVE_GL(); @@ -6065,15 +6012,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i if (SUCCEEDED(IWineD3DSurface_LockRect(pCursorBitmap, &rect, NULL, WINED3DLOCK_READONLY))) { const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; - const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); struct wined3d_context *context; char *mem, *bits = rect.pBits; - GLint intfmt = glDesc->glInternal; - GLint format = glDesc->glFormat; - GLint type = glDesc->glType; + GLint intfmt = format_desc->glInternal; + GLint format = format_desc->glFormat; + GLint type = format_desc->glType; INT height = This->cursorHeight; INT width = This->cursorWidth; - INT bpp = glDesc->byte_count; + INT bpp = format_desc->byte_count; DWORD sampler; INT i; @@ -6084,7 +6031,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp); IWineD3DSurface_UnlockRect(pCursorBitmap); - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); ENTER_GL(); @@ -6258,14 +6205,10 @@ static HRESULT updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRES while (surface->pow2Width < pPresentationParameters->BackBufferWidth) surface->pow2Width <<= 1; while (surface->pow2Height < pPresentationParameters->BackBufferHeight) surface->pow2Height <<= 1; } - surface->glRect.left = 0; - surface->glRect.top = 0; - surface->glRect.right = surface->pow2Width; - surface->glRect.bottom = surface->pow2Height; if (surface->texture_name) { - struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); glDeleteTextures(1, &surface->texture_name); LEAVE_GL(); @@ -6286,7 +6229,7 @@ static HRESULT updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRES /* Put all surfaces into sysmem - the drawable might disappear if the backbuffer was rendered * to a FBO */ - if(!surface_init_sysmem((IWineD3DSurface *) surface)) + if (!surface_init_sysmem(surface)) { return E_OUTOFMEMORY; } @@ -6327,14 +6270,14 @@ static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, const WINED3DPRE return FALSE; } -void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { +static void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; IWineD3DBaseShaderImpl *shader; - context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This, NULL); gl_info = context->gl_info; IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL); @@ -6371,9 +6314,9 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_ swapchain->num_contexts = 0; } -HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) { +static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface; struct wined3d_context *context; HRESULT hr; IWineD3DSurfaceImpl *target; @@ -6386,9 +6329,8 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain * return E_OUTOFMEMORY; } - target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer); - context = context_create(This, target, swapchain->win_handle, FALSE, &swapchain->presentParms); - if (!context) + target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer; + if (!(context = context_create(swapchain, target, swapchain->ds_format))) { WARN("Failed to create context.\n"); HeapFree(GetProcessHeap(), 0, swapchain->context); @@ -6427,7 +6369,7 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain * return WINED3D_OK; err: - context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD); + context_acquire(This, NULL); destroy_dummy_textures(This, context->gl_info); context_release(context); context_destroy(This, context); @@ -6499,7 +6441,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE pPresentationParameters->hDeviceWindow != swapchain->presentParms.hDeviceWindow) { ERR("Cannot change the device window yet\n"); } - if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) { + if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil) + { HRESULT hrc; TRACE("Creating the depth stencil buffer\n"); @@ -6512,7 +6455,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE pPresentationParameters->MultiSampleType, pPresentationParameters->MultiSampleQuality, FALSE, - &This->auto_depth_stencil_buffer); + (IWineD3DSurface **)&This->auto_depth_stencil); if (FAILED(hrc)) { ERR("Failed to create the depth stencil buffer\n"); @@ -6521,9 +6464,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } + if (This->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->onscreen_depth_stencil); + This->onscreen_depth_stencil = NULL; + } + /* Reset the depth stencil */ if (pPresentationParameters->EnableAutoDepthStencil) - IWineD3DDevice_SetDepthStencilSurface(iface, This->auto_depth_stencil_buffer); + IWineD3DDevice_SetDepthStencilSurface(iface, (IWineD3DSurface *)This->auto_depth_stencil); else IWineD3DDevice_SetDepthStencilSurface(iface, NULL); @@ -6531,7 +6480,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock); IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock); - delete_opengl_contexts(iface, (IWineD3DSwapChain *) swapchain); + delete_opengl_contexts(iface, swapchain); if(pPresentationParameters->Windowed) { mode.Width = swapchain->orig_width; @@ -6558,23 +6507,25 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE swapchain->presentParms.BackBufferWidth = pPresentationParameters->BackBufferWidth; swapchain->presentParms.BackBufferHeight = pPresentationParameters->BackBufferHeight; - hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters); + hr = updateSurfaceDesc(swapchain->front_buffer, pPresentationParameters); if(FAILED(hr)) { IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } - for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) { - hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters); + for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) + { + hr = updateSurfaceDesc(swapchain->back_buffers[i], pPresentationParameters); if(FAILED(hr)) { IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } } - if(This->auto_depth_stencil_buffer) { - hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters); + if (This->auto_depth_stencil) + { + hr = updateSurfaceDesc(This->auto_depth_stencil, pPresentationParameters); if(FAILED(hr)) { IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); @@ -6583,24 +6534,26 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } - if((pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) || - (swapchain->presentParms.Windowed && !pPresentationParameters->Windowed) || - DisplayModeChanged) { - + if (!pPresentationParameters->Windowed != !swapchain->presentParms.Windowed + || DisplayModeChanged) + { IWineD3DDevice_SetDisplayMode(iface, 0, &mode); - if(swapchain->win_handle && !pPresentationParameters->Windowed) { + if (!pPresentationParameters->Windowed) + { if(swapchain->presentParms.Windowed) { /* switch from windowed to fs */ swapchain_setup_fullscreen_window(swapchain, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight); } else { /* Fullscreen -> fullscreen mode change */ - MoveWindow(swapchain->win_handle, 0, 0, + MoveWindow(swapchain->device_window, 0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight, TRUE); } - } else if(swapchain->win_handle && !swapchain->presentParms.Windowed) { + } + else if (!swapchain->presentParms.Windowed) + { /* Fullscreen -> windowed switch */ swapchain_restore_fullscreen_window(swapchain); } @@ -6657,7 +6610,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE } } - hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *) swapchain); + hr = create_primary_opengl_context(iface, swapchain); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); /* All done. There is no need to reload resources or shaders, this will happen automatically on the @@ -6747,13 +6700,11 @@ void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resour { for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i) { - if (This->render_targets[i] == (IWineD3DSurface *)resource) { + if (This->render_targets[i] == (IWineD3DSurfaceImpl *)resource) This->render_targets[i] = NULL; - } - } - if (This->stencilBufferTarget == (IWineD3DSurface *)resource) { - This->stencilBufferTarget = NULL; } + if (This->depth_stencil == (IWineD3DSurfaceImpl *)resource) + This->depth_stencil = NULL; } break; @@ -6845,6 +6796,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EnumResources(IWineD3DDevice *iface, D3 return WINED3D_OK; } +static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC(IWineD3DDevice *iface, HDC dc, IWineD3DSurface **surface) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + IWineD3DResourceImpl *resource; + + LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry) + { + WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource); + if (type == WINED3DRTYPE_SURFACE) + { + if (((IWineD3DSurfaceImpl *)resource)->hDC == dc) + { + TRACE("Found surface %p for dc %p.\n", resource, dc); + *surface = (IWineD3DSurface *)resource; + return WINED3D_OK; + } + } + } + + return WINED3DERR_INVALIDCALL; +} + /********************************************************** * IWineD3DDevice VTbl follows **********************************************************/ @@ -6993,7 +6966,10 @@ static const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_UpdateSurface, IWineD3DDeviceImpl_GetFrontBufferData, /*** object tracking ***/ - IWineD3DDeviceImpl_EnumResources + IWineD3DDeviceImpl_EnumResources, + IWineD3DDeviceImpl_GetSurfaceFromDC, + IWineD3DDeviceImpl_AcquireFocusWindow, + IWineD3DDeviceImpl_ReleaseFocusWindow, }; HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, @@ -7045,27 +7021,29 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, select_shader_mode(&adapter->gl_info, &device->ps_selected_mode, &device->vs_selected_mode); device->shader_backend = adapter->shader_backend; - memset(&shader_caps, 0, sizeof(shader_caps)); - device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); - device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst; - device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst; - device->vs_clipping = shader_caps.VSClipping; - - memset(&ffp_caps, 0, sizeof(ffp_caps)); + if (device->shader_backend) + { + device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); + device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst; + device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst; + device->vs_clipping = shader_caps.VSClipping; + } fragment_pipeline = adapter->fragment_pipe; device->frag_pipe = fragment_pipeline; - fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps); - device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures; - - hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info, - ffp_vertexstate_template, fragment_pipeline, misc_state_template); - if (FAILED(hr)) + if (fragment_pipeline) { - ERR("Failed to compile state table, hr %#x.\n", hr); - IWineD3D_Release(device->wined3d); - return hr; - } + fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps); + device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures; + hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info, + ffp_vertexstate_template, fragment_pipeline, misc_state_template); + if (FAILED(hr)) + { + ERR("Failed to compile state table, hr %#x.\n", hr); + IWineD3D_Release(device->wined3d); + return hr; + } + } device->blitter = adapter->blitter; return WINED3D_OK; @@ -7090,31 +7068,21 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) { } } -void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height) -{ - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.device; - /* The drawable size of a pbuffer render target is the current pbuffer size. */ - *width = device->pbufferWidth; - *height = device->pbufferHeight; -} - void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt; /* The drawable size of a fbo target is the opengl texture size, which is the power of two size. */ - *width = surface->pow2Width; - *height = surface->pow2Height; + *width = context->current_rt->pow2Width; + *height = context->current_rt->pow2Height; } void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface; + IWineD3DSwapChainImpl *swapchain = context->swapchain; /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the * current context's drawable, which is the size of the back buffer of the swapchain - * the active context belongs to. The back buffer of the swapchain is stored as the - * surface the context belongs to. */ - *width = surface->currentDesc.Width; - *height = surface->currentDesc.Height; + * the active context belongs to. */ + *width = swapchain->presentParms.BackBufferWidth; + *height = swapchain->presentParms.BackBufferHeight; } LRESULT device_process_message(IWineD3DDeviceImpl *device, HWND window, diff --git a/dll/directx/wine/wined3d/directx.c b/dll/directx/wine/wined3d/directx.c index 812e5ccc9e8..29061476ddd 100644 --- a/dll/directx/wine/wined3d/directx.c +++ b/dll/directx/wine/wined3d/directx.c @@ -24,14 +24,13 @@ */ #include "config.h" +#include #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); -#define GLINFO_LOCATION (*gl_info) #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024) -#define MAKEDWORD_VERSION(maj, min) ((maj & 0xffff) << 16) | (min & 0xffff) /* The d3d device ID */ static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } }; @@ -74,6 +73,7 @@ static const struct { {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 }, {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 }, {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100, 0 }, + {"GL_ARB_shadow", ARB_SHADOW, 0 }, {"GL_ARB_sync", ARB_SYNC, 0 }, {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP, 0 }, {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION, 0 }, @@ -104,6 +104,7 @@ static const struct { {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE, 0 }, {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE, 0 }, {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX, 0 }, + {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2, 0 }, {"GL_EXT_fog_coord", EXT_FOG_COORD, 0 }, {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT, 0 }, {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE, 0 }, @@ -325,12 +326,12 @@ fail: } /* Adjust the amount of used texture memory */ -long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram) +unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *device, unsigned int glram) { - struct wined3d_adapter *adapter = D3DDevice->adapter; + struct wined3d_adapter *adapter = device->adapter; adapter->UsedTextureRam += glram; - TRACE("Adjusted gl ram by %ld to %d\n", glram, adapter->UsedTextureRam); + TRACE("Adjusted gl ram by %d to %d\n", glram, adapter->UsedTextureRam); return adapter->UsedTextureRam; } @@ -528,9 +529,12 @@ static void test_pbo_functionality(struct wined3d_gl_info *gl_info) checkGLcall("Loading the PBO test texture"); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); + LEAVE_GL(); + wglFinish(); /* just to be sure */ memset(check, 0, sizeof(check)); + ENTER_GL(); glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check); checkGLcall("Reading back the PBO test texture"); @@ -570,7 +574,7 @@ static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) { - return (gl_vendor == GL_VENDOR_ATI); + return gl_vendor == GL_VENDOR_FGLRX; } @@ -669,6 +673,61 @@ static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const ch return ret; } +/* Context activation is done by the caller. */ +static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer, + enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device) +{ + char data[4 * 4 * 4]; + GLuint tex, fbo; + GLenum status; + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE; + + memset(data, 0xcc, sizeof(data)); + + ENTER_GL(); + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + checkGLcall("glTexImage2D"); + + gl_info->fbo_ops.glGenFramebuffers(1, &fbo); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + checkGLcall("glFramebufferTexture2D"); + + status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status); + checkGLcall("glCheckFramebufferStatus"); + + memset(data, 0x11, sizeof(data)); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glTexSubImage2D"); + + glClearColor(0.996, 0.729, 0.745, 0.792); + glClear(GL_COLOR_BUFFER_BIT); + checkGLcall("glClear"); + + glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); + checkGLcall("glGetTexImage"); + + gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + checkGLcall("glBindTexture"); + + gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); + checkGLcall("glDeleteTextures"); + + LEAVE_GL(); + + return *(DWORD *)data == 0x11111111; +} + static void quirk_arb_constants(struct wined3d_gl_info *gl_info) { TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants); @@ -797,6 +856,11 @@ static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info) gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN; } +static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info) +{ + gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE; +} + struct driver_quirk { BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, @@ -876,6 +940,11 @@ static const struct driver_quirk quirk_table[] = quirk_disable_nvvp_clip, "Apple NV_vertex_program clip bug quirk" }, + { + match_fbo_tex_update, + quirk_fbo_tex_update, + "FBO rebind for attachment updates" + }, }; /* Certain applications (Steam) complain if we report an outdated driver version. In general, @@ -955,7 +1024,7 @@ static const struct driver_version_information driver_version_table[] = {HW_VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 14, 10, 6764 }, - {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2300, "ATI Mobility Radeon HD 2300", 14, 10, 6764 }, + {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2350, "ATI Mobility Radeon HD 2350", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 14, 10, 6764 }, {HW_VENDOR_ATI, CARD_ATI_RADEON_HD4350, "ATI Radeon HD 4350", 14, 10, 6764 }, @@ -1131,10 +1200,11 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl return GL_VENDOR_NVIDIA; if (strstr(gl_vendor_string, "ATI")) - return GL_VENDOR_ATI; + return GL_VENDOR_FGLRX; if (strstr(gl_vendor_string, "Intel(R)") - || strstr(gl_renderer, "Intel(R)") + /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */ + || strstr(gl_renderer, "Intel") || strstr(gl_vendor_string, "Intel Inc.")) return GL_VENDOR_INTEL; @@ -1148,9 +1218,10 @@ static enum wined3d_gl_vendor wined3d_guess_gl_vendor(struct wined3d_gl_info *gl || strstr(gl_renderer, "Gallium")) return GL_VENDOR_MESA; - FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_WINE.\n", debugstr_a(gl_vendor_string)); + FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n", + debugstr_a(gl_vendor_string)); - return GL_VENDOR_WINE; + return GL_VENDOR_UNKNOWN; } static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer) @@ -1165,14 +1236,15 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s return HW_VENDOR_ATI; if (strstr(gl_vendor_string, "Intel(R)") - || strstr(gl_renderer, "Intel(R)") + /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */ + || strstr(gl_renderer, "Intel") || strstr(gl_vendor_string, "Intel Inc.")) return HW_VENDOR_INTEL; if (strstr(gl_vendor_string, "Mesa") || strstr(gl_vendor_string, "Tungsten Graphics, Inc") || strstr(gl_vendor_string, "VMware, Inc.")) - return HW_VENDOR_WINE; + return HW_VENDOR_SOFTWARE; FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string)); @@ -1181,13 +1253,10 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s -enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { - /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more - * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx. - */ - if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3]) + if (WINE_D3D10_CAPABLE(gl_info)) { /* Geforce 200 - highend */ if (strstr(gl_renderer, "GTX 280") @@ -1293,6 +1362,16 @@ enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info * return CARD_NVIDIA_GEFORCE_8300GS; } + /* Geforce8-compatible fall back if the GPU is not in the list yet */ + *vidmem = 128; + return CARD_NVIDIA_GEFORCE_8300GS; + } + + /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more + * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx. + */ + if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3]) + { /* Geforce7 - highend */ if (strstr(gl_renderer, "7800") || strstr(gl_renderer, "7900") @@ -1425,14 +1504,14 @@ enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info * } -enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx * * Beware: renderer string do not match exact card model, * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */ - if (WINE_D3D9_CAPABLE(gl_info)) + if (WINE_D3D10_CAPABLE(gl_info)) { /* Radeon EG CYPRESS XT / PRO HD5800 - highend */ if (strstr(gl_renderer, "HD 5800") /* Radeon EG CYPRESS HD58xx generic renderer string */ @@ -1507,16 +1586,17 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_HD2600; } - /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */ - if (strstr(gl_renderer, "HD 2300") + /* Radeon R6xx HD2350/HD2400/HD3400 - lowend + * Note HD2300=DX9, HD2350=DX10 */ + if (strstr(gl_renderer, "HD 2350") || strstr(gl_renderer, "HD 2400") || strstr(gl_renderer, "HD 3470") || strstr(gl_renderer, "HD 3450") || strstr(gl_renderer, "HD 3430") || strstr(gl_renderer, "HD 3400")) { - *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */ - return CARD_ATI_RADEON_HD2300; + *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */ + return CARD_ATI_RADEON_HD2350; } /* Radeon R6xx/R7xx integrated */ @@ -1528,6 +1608,13 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_HD3200; } + /* Default for when no GPU has been found */ + *vidmem = 128; /* 128MB */ + return CARD_ATI_RADEON_HD3200; + } + + if (WINE_D3D8_CAPABLE(gl_info)) + { /* Radeon R5xx */ if (strstr(gl_renderer, "X1600") || strstr(gl_renderer, "X1650") @@ -1539,14 +1626,19 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_X1600; } - /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */ + /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx) + * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */ if (strstr(gl_renderer, "X700") || strstr(gl_renderer, "X800") || strstr(gl_renderer, "X850") || strstr(gl_renderer, "X1300") || strstr(gl_renderer, "X1400") || strstr(gl_renderer, "X1450") - || strstr(gl_renderer, "X1550")) + || strstr(gl_renderer, "X1550") + || strstr(gl_renderer, "X2300") + || strstr(gl_renderer, "X2500") + || strstr(gl_renderer, "HD 2300") + ) { *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */ return CARD_ATI_RADEON_X700; @@ -1581,8 +1673,8 @@ enum wined3d_pci_device select_card_ati_binary(const struct wined3d_gl_info *gl_ } -enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { if (strstr(gl_renderer, "X3100")) { @@ -1607,8 +1699,8 @@ enum wined3d_pci_device select_card_intel_binary(const struct wined3d_gl_info *g } -enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_ati_mesa(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx * @@ -1663,12 +1755,12 @@ enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_ return CARD_ATI_RADEON_HD2600; } - /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */ + /* Radeon R6xx HD2350/HD2400/HD3400 - lowend */ if (strstr(gl_renderer, "RV610") || strstr(gl_renderer, "RV620")) { - *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */ - return CARD_ATI_RADEON_HD2300; + *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */ + return CARD_ATI_RADEON_HD2350; } /* Radeon R6xx/R7xx integrated */ @@ -1786,8 +1878,8 @@ enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_ if (strstr(gl_renderer, "(RV610") || strstr(gl_renderer, "(RV620")) { - *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */ - return CARD_ATI_RADEON_HD2300; + *vidmem = 256; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */ + return CARD_ATI_RADEON_HD2350; } /* Radeon R6xx/R7xx integrated */ @@ -1816,8 +1908,8 @@ enum wined3d_pci_device (select_card_ati_mesa)(const struct wined3d_gl_info *gl_ } -enum wined3d_pci_device (select_card_nvidia_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { FIXME_(d3d_caps)("Card selection not handled for Mesa Nouveau driver\n"); if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600; @@ -1827,8 +1919,8 @@ enum wined3d_pci_device (select_card_nvidia_mesa)(const struct wined3d_gl_info * return CARD_NVIDIA_RIVA_128; } -enum wined3d_pci_device (select_card_intel_mesa)(const struct wined3d_gl_info *gl_info, const char *gl_renderer, - unsigned int *vidmem ) +static enum wined3d_pci_device select_card_intel_mesa(const struct wined3d_gl_info *gl_info, + const char *gl_renderer, unsigned int *vidmem) { FIXME_(d3d_caps)("Card selection not handled for Mesa Intel driver\n"); return CARD_INTEL_I915G; @@ -1850,10 +1942,11 @@ static const struct vendor_card_selection vendor_card_select_table[] = {GL_VENDOR_APPLE, HW_VENDOR_NVIDIA, "Apple OSX NVidia binary driver", select_card_nvidia_binary}, {GL_VENDOR_APPLE, HW_VENDOR_ATI, "Apple OSX AMD/ATI binary driver", select_card_ati_binary}, {GL_VENDOR_APPLE, HW_VENDOR_INTEL, "Apple OSX Intel binary driver", select_card_intel_binary}, - {GL_VENDOR_ATI, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary}, + {GL_VENDOR_FGLRX, HW_VENDOR_ATI, "AMD/ATI binary driver", select_card_ati_binary}, {GL_VENDOR_MESA, HW_VENDOR_ATI, "Mesa AMD/ATI driver", select_card_ati_mesa}, {GL_VENDOR_MESA, HW_VENDOR_NVIDIA, "Mesa Nouveau driver", select_card_nvidia_mesa}, - {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa} + {GL_VENDOR_MESA, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa}, + {GL_VENDOR_INTEL, HW_VENDOR_INTEL, "Mesa Intel driver", select_card_intel_mesa} }; @@ -2034,6 +2127,7 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter) * with Default values */ memset(gl_info->supported, 0, sizeof(gl_info->supported)); + gl_info->limits.blends = 1; gl_info->limits.buffers = 1; gl_info->limits.textures = 1; gl_info->limits.fragment_samplers = 1; @@ -2347,7 +2441,13 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter) if (gl_info->supported[ARB_SHADING_LANGUAGE_100]) { const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); + unsigned int major, minor; + TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str)); + + /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */ + sscanf(str, "%u.%u", &major, &minor); + gl_info->glsl_version = MAKEDWORD_VERSION(major, minor); } if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) { @@ -2522,10 +2622,6 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter) ThisExtn[len] = '\0'; TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn)); - if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) { - gl_info->supported[WGL_ARB_PBUFFER] = TRUE; - TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n"); - } if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) { gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE; TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n"); @@ -2590,7 +2686,7 @@ static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Ad /* TODO: Store modes per adapter and read it from the adapter structure */ if (Adapter == 0) { /* Display */ - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); UINT format_bits = format_desc->byte_count * CHAR_BIT; unsigned int i = 0; unsigned int j = 0; @@ -2637,7 +2733,7 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte /* TODO: Store modes per adapter and read it from the adapter structure */ if (Adapter == 0) { - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(Format, &This->adapters[Adapter].gl_info); UINT format_bits = format_desc->byte_count * CHAR_BIT; DEVMODEW DevModeW; int ModeIdx = 0; @@ -2802,13 +2898,16 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad } static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info, - const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc) + const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc) { short redSize, greenSize, blueSize, alphaSize, colorBits; if(!cfg) return FALSE; + /* Float formats need FBOs. If FBOs are used this function isn't called */ + if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE; + if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */ if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) { @@ -2829,29 +2928,14 @@ static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined return FALSE; return TRUE; - } else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */ - if (format_desc->format == WINED3DFMT_R16_FLOAT) - return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R16G16_FLOAT) - return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R16G16B16A16_FLOAT) - return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16); - if (format_desc->format == WINED3DFMT_R32_FLOAT) - return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R32G32_FLOAT) - return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0); - if (format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT) - return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32); - } else { - /* Probably a color index mode */ - return FALSE; } + /* Probably a RGBA_float or color index mode */ return FALSE; } static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info, - const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc) + const WineD3D_PixelFormat *cfg, const struct wined3d_format_desc *format_desc) { short depthSize, stencilSize; BOOL lockable = FALSE; @@ -2865,6 +2949,9 @@ static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3 return FALSE; } + /* Float formats need FBOs. If FBOs are used this function isn't called */ + if (format_desc->Flags & WINED3DFMT_FLAG_FLOAT) return FALSE; + if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32_FLOAT)) lockable = TRUE; @@ -2890,8 +2977,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT int nCfgs; const WineD3D_PixelFormat *cfgs; const struct wined3d_adapter *adapter; - const struct GlPixelFormatDesc *rt_format_desc; - const struct GlPixelFormatDesc *ds_format_desc; + const struct wined3d_format_desc *rt_format_desc; + const struct wined3d_format_desc *ds_format_desc; int it; WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n", @@ -2909,15 +2996,26 @@ static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT adapter = &This->adapters[Adapter]; rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info); ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info); - cfgs = adapter->cfgs; - nCfgs = adapter->nCfgs; - for (it = 0; it < nCfgs; ++it) { - if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc)) - { - if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc)) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if ((rt_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET) && + (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) { + TRACE_(d3d_caps)("(%p) : Formats matched\n", This); + return WINED3D_OK; + } + } + else + { + cfgs = adapter->cfgs; + nCfgs = adapter->nCfgs; + for (it = 0; it < nCfgs; ++it) { + if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc)) { - TRACE_(d3d_caps)("(%p) : Formats matched\n", This); - return WINED3D_OK; + if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc)) + { + TRACE_(d3d_caps)("(%p) : Formats matched\n", This); + return WINED3D_OK; + } } } } @@ -2930,7 +3028,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels) { IWineD3DImpl *This = (IWineD3DImpl *)iface; - const struct GlPixelFormatDesc *glDesc; + const struct wined3d_format_desc *glDesc; const struct wined3d_adapter *adapter; TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n", @@ -3109,51 +3207,41 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter /* Check if we support bumpmapping for a format */ -static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckBumpMapCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { - switch(format_desc->format) - { - case WINED3DFMT_R8G8_SNORM: - case WINED3DFMT_R16G16_SNORM: - case WINED3DFMT_R5G5_SNORM_L6_UNORM: - case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: - case WINED3DFMT_R8G8B8A8_SNORM: - /* Ask the fixed function pipeline implementation if it can deal - * with the conversion. If we've got a GL extension giving native - * support this will be an identity conversion. */ - if (adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup)) - { - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - } - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - - default: - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } + /* Ask the fixed function pipeline implementation if it can deal + * with the conversion. If we've got a GL extension giving native + * support this will be an identity conversion. */ + return (format_desc->Flags & WINED3DFMT_FLAG_BUMPMAP) + && adapter->fragment_pipe->color_fixup_supported(format_desc->color_fixup); } /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */ static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter, - const struct GlPixelFormatDesc *display_format_desc, const struct GlPixelFormatDesc *ds_format_desc) + const struct wined3d_format_desc *display_format_desc, const struct wined3d_format_desc *ds_format_desc) { int it=0; /* Only allow depth/stencil formats */ if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE; - /* Walk through all WGL pixel formats to find a match */ - for (it = 0; it < adapter->nCfgs; ++it) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - WineD3D_PixelFormat *cfg = &adapter->cfgs[it]; - if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc)) + /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */ + if (ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE; + } + else + { + /* Walk through all WGL pixel formats to find a match */ + for (it = 0; it < adapter->nCfgs; ++it) { - if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc)) + WineD3D_PixelFormat *cfg = &adapter->cfgs[it]; + if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc)) { - return TRUE; + if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc)) + { + return TRUE; + } } } } @@ -3161,7 +3249,7 @@ static BOOL CheckDepthStencilCapability(struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { /* The flags entry of a format contains the filtering capability */ if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE; @@ -3171,11 +3259,10 @@ static BOOL CheckFilterCapability(struct wined3d_adapter *adapter, const struct /* Check the render target capabilities of a format */ static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter, - const struct GlPixelFormatDesc *adapter_format_desc, const struct GlPixelFormatDesc *check_format_desc) + const struct wined3d_format_desc *adapter_format_desc, const struct wined3d_format_desc *check_format_desc) { /* Filter out non-RT formats */ if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE; - if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) { WineD3D_PixelFormat *cfgs = adapter->cfgs; int it; @@ -3204,23 +3291,9 @@ static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter, return TRUE; } } - } else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) { - /* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */ - WineD3D_PixelFormat *cfgs = adapter->cfgs; - int it; - - /* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */ - for (it = 0; it < adapter->nCfgs; ++it) - { - if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, - &cfgs[it], check_format_desc)) - { - TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", - cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format)); - return TRUE; - } - } - } else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO){ + } + else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { /* For now return TRUE for FBOs until we have some proper checks. * Note that this function will only be called when the format is around for texturing. */ return TRUE; @@ -3228,46 +3301,18 @@ static BOOL CheckRenderTargetCapability(struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckSrgbReadCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - - /* Check for supported sRGB formats (Texture loading and framebuffer) */ - if (!gl_info->supported[EXT_TEXTURE_SRGB]) - { - TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n"); - return FALSE; - } - - switch (format_desc->format) - { - case WINED3DFMT_B8G8R8A8_UNORM: - case WINED3DFMT_B8G8R8X8_UNORM: - case WINED3DFMT_B4G4R4A4_UNORM: - case WINED3DFMT_L8_UNORM: - case WINED3DFMT_L8A8_UNORM: - case WINED3DFMT_DXT1: - case WINED3DFMT_DXT2: - case WINED3DFMT_DXT3: - case WINED3DFMT_DXT4: - case WINED3DFMT_DXT5: - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - - default: - TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format)); - return FALSE; - } - return FALSE; + return adapter->gl_info.supported[EXT_TEXTURE_SRGB] + && (format_desc->Flags & WINED3DFMT_FLAG_SRGB_READ); } -static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are * doing the color fixup in shaders. * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */ - if ((format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) || (format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)) + if (format_desc->Flags & WINED3DFMT_FLAG_SRGB_WRITE) { int vs_selected_mode; int ps_selected_mode; @@ -3285,7 +3330,7 @@ static BOOL CheckSrgbWriteCapability(struct wined3d_adapter *adapter, /* Check if a format support blending in combination with pixel shaders */ static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapter, - const struct GlPixelFormatDesc *format_desc) + const struct wined3d_format_desc *format_desc) { /* The flags entry of a format contains the post pixel shader blending capability */ if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE; @@ -3293,7 +3338,7 @@ static BOOL CheckPostPixelShaderBlendingCapability(struct wined3d_adapter *adapt return FALSE; } -static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported, * but we have to report mipmapping so we cannot reject this flag. Tests show that @@ -3308,8 +3353,7 @@ static BOOL CheckWrapAndMipCapability(struct wined3d_adapter *adapter, const str } /* Check if a texture format is supported on the given adapter */ -static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, const struct wined3d_format_desc *format_desc) { const struct wined3d_gl_info *gl_info = &adapter->gl_info; @@ -3340,12 +3384,12 @@ static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, return FALSE; /***** - * supported: Palettized + * Not supported: Palettized + * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7. + * Since it is not widely available, don't offer it. Further no Windows driver offers + * WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either. */ case WINED3DFMT_P8_UINT: - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - /* No Windows driver offers WINED3DFMT_P8_UINT_A8_UNORM, so don't offer it either */ case WINED3DFMT_P8_UINT_A8_UNORM: return FALSE; @@ -3539,8 +3583,10 @@ static BOOL CheckTextureCapability(struct wined3d_adapter *adapter, return FALSE; } -static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *adapter_format_desc, - WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *check_format_desc, WINED3DSURFTYPE SurfaceType) +static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, + const struct wined3d_format_desc *adapter_format_desc, + const struct wined3d_format_desc *check_format_desc, + WINED3DSURFTYPE SurfaceType) { if(SurfaceType == SURFACE_GDI) { switch(check_format_desc->format) @@ -3572,12 +3618,14 @@ static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct } /* All format that are supported for textures are supported for surfaces as well */ - if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE; + if (CheckTextureCapability(adapter, check_format_desc)) return TRUE; /* All depth stencil formats are supported on surfaces */ if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE; /* If opengl can't process the format natively, the blitter may be able to convert it */ - if (adapter->blitter->color_fixup_supported(check_format_desc->color_fixup)) + if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT, + NULL, WINED3DPOOL_DEFAULT, 0, check_format_desc, + NULL, WINED3DPOOL_DEFAULT, 0, adapter_format_desc)) { TRACE_(d3d_caps)("[OK]\n"); return TRUE; @@ -3588,32 +3636,11 @@ static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter, const struct return FALSE; } -static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter, const struct GlPixelFormatDesc *format_desc) +static BOOL CheckVertexTextureCapability(struct wined3d_adapter *adapter, + const struct wined3d_format_desc *format_desc) { - const struct wined3d_gl_info *gl_info = &adapter->gl_info; - - if (!gl_info->limits.vertex_samplers) - { - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - - switch (format_desc->format) - { - case WINED3DFMT_R32G32B32A32_FLOAT: - if (!gl_info->supported[ARB_TEXTURE_FLOAT]) - { - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - TRACE_(d3d_caps)("[OK]\n"); - return TRUE; - - default: - TRACE_(d3d_caps)("[FAILED]\n"); - return FALSE; - } - return FALSE; + return adapter->gl_info.limits.vertex_samplers + && (format_desc->Flags & WINED3DFMT_FLAG_VTF); } static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, @@ -3623,8 +3650,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt IWineD3DImpl *This = (IWineD3DImpl *)iface; struct wined3d_adapter *adapter = &This->adapters[Adapter]; const struct wined3d_gl_info *gl_info = &adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info); - const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(CheckFormat, gl_info); + const struct wined3d_format_desc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info); DWORD UsageCaps = 0; TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n", @@ -3640,484 +3667,476 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt return WINED3DERR_INVALIDCALL; } - if(RType == WINED3DRTYPE_CUBETEXTURE) { - - if(SurfaceType != SURFACE_OPENGL) { - TRACE("[FAILED]\n"); - return WINED3DERR_NOTAVAILABLE; - } - - /* Cubetexture allows: - * - D3DUSAGE_AUTOGENMIPMAP - * - D3DUSAGE_DEPTHSTENCIL - * - D3DUSAGE_DYNAMIC - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_RENDERTARGET - * - D3DUSAGE_SOFTWAREPROCESSING - * - D3DUSAGE_QUERY_WRAPANDMIP - */ - if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) - { - /* Check if the texture format is around */ - if (CheckTextureCapability(adapter, DeviceType, format_desc)) + switch (RType) + { + case WINED3DRTYPE_CUBETEXTURE: + /* Cubetexture allows: + * - WINED3DUSAGE_AUTOGENMIPMAP + * - WINED3DUSAGE_DEPTHSTENCIL + * - WINED3DUSAGE_DYNAMIC + * - WINED3DUSAGE_NONSECURE (d3d9ex) + * - WINED3DUSAGE_RENDERTARGET + * - WINED3DUSAGE_SOFTWAREPROCESSING + * - WINED3DUSAGE_QUERY_WRAPANDMIP + */ + if (SurfaceType != SURFACE_OPENGL) { - if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { - /* Check for automatic mipmap generation support */ - if (gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; - } else { - /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */ - TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n"); - } - } + TRACE_(d3d_caps)("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } - /* Always report dynamic locking */ - if(Usage & WINED3DUSAGE_DYNAMIC) - UsageCaps |= WINED3DUSAGE_DYNAMIC; + if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP]) + { + TRACE_(d3d_caps)("[FAILED] - No cube texture support\n"); + return WINED3DERR_NOTAVAILABLE; + } - if(Usage & WINED3DUSAGE_RENDERTARGET) { - if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) - { - UsageCaps |= WINED3DUSAGE_RENDERTARGET; - } else { - TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Always report software processing */ - if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING) - UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; - - /* Check QUERY_FILTER support */ - if(Usage & WINED3DUSAGE_QUERY_FILTER) { - if (CheckFilterCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_FILTER; - } else { - TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { - TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_SRGBREAD support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) { - if (CheckSrgbReadCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; - } else { - TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_SRGBWRITE support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) { - if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; - } else { - TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_VERTEXTEXTURE support */ - if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) { - if (CheckVertexTextureCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; - } else { - TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_WRAPANDMIP support */ - if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) { - if (CheckWrapAndMipCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; - } else { - TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - } else { + if (!CheckTextureCapability(adapter, format_desc)) + { TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n"); return WINED3DERR_NOTAVAILABLE; } - } else { - TRACE_(d3d_caps)("[FAILED] - No cube texture support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } else if(RType == WINED3DRTYPE_SURFACE) { - /* Surface allows: - * - D3DUSAGE_DEPTHSTENCIL - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_RENDERTARGET - */ - if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType)) - { - if(Usage & WINED3DUSAGE_DEPTHSTENCIL) { - if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) - { - UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; - } else { - TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - if(Usage & WINED3DUSAGE_RENDERTARGET) { - if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) - { - UsageCaps |= WINED3DUSAGE_RENDERTARGET; - } else { - TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { - TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - } else { - TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n"); - return WINED3DERR_NOTAVAILABLE; - } - - } else if(RType == WINED3DRTYPE_TEXTURE) { - /* Texture allows: - * - D3DUSAGE_AUTOGENMIPMAP - * - D3DUSAGE_DEPTHSTENCIL - * - D3DUSAGE_DMAP - * - D3DUSAGE_DYNAMIC - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_RENDERTARGET - * - D3DUSAGE_SOFTWAREPROCESSING - * - D3DUSAGE_TEXTAPI (d3d9ex) - * - D3DUSAGE_QUERY_WRAPANDMIP - */ - - if(SurfaceType != SURFACE_OPENGL) { - TRACE("[FAILED]\n"); - return WINED3DERR_NOTAVAILABLE; - } - - /* Check if the texture format is around */ - if (CheckTextureCapability(adapter, DeviceType, format_desc)) - { - if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { - /* Check for automatic mipmap generation support */ - if (gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; - } else { - /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUTOGEN instead of D3D_OK */ + if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) + { + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + /* When autogenmipmap isn't around continue and return + * WINED3DOK_NOAUTOGEN instead of D3D_OK. */ TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n"); - } + else + UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; } - /* Always report dynamic locking */ - if(Usage & WINED3DUSAGE_DYNAMIC) + /* Always report dynamic locking. */ + if (Usage & WINED3DUSAGE_DYNAMIC) UsageCaps |= WINED3DUSAGE_DYNAMIC; - if(Usage & WINED3DUSAGE_RENDERTARGET) { - if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) + if (Usage & WINED3DUSAGE_RENDERTARGET) + { + if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) { - UsageCaps |= WINED3DUSAGE_RENDERTARGET; - } else { TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); - return WINED3DERR_NOTAVAILABLE; - } + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_RENDERTARGET; } - /* Always report software processing */ - if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING) + /* Always report software processing. */ + if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING) UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; - /* Check QUERY_FILTER support */ - if(Usage & WINED3DUSAGE_QUERY_FILTER) { - if (CheckFilterCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_FILTER) + { + if (!CheckFilterCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_FILTER; - } else { TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_FILTER; } - /* Check QUERY_LEGACYBUMPMAP support */ - if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) { - if (CheckBumpMapCapability(adapter, DeviceType, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP; - } else { - TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n"); - return WINED3DERR_NOTAVAILABLE; - } - } - - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) - { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; } - /* Check QUERY_SRGBREAD support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) { - if (CheckSrgbReadCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) + { + if (!CheckSrgbReadCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; } - /* Check QUERY_SRGBWRITE support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) { - if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE) + { + if (!CheckSrgbWriteCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; } - /* Check QUERY_VERTEXTEXTURE support */ - if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) { - if (CheckVertexTextureCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) + { + if (!CheckVertexTextureCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; - } else { TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; } - /* Check QUERY_WRAPANDMIP support */ - if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) { - if (CheckWrapAndMipCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) + { + if (!CheckWrapAndMipCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; - } else { TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; + } + break; + + case WINED3DRTYPE_SURFACE: + /* Surface allows: + * - WINED3DUSAGE_DEPTHSTENCIL + * - WINED3DUSAGE_NONSECURE (d3d9ex) + * - WINED3DUSAGE_RENDERTARGET + */ + if (!CheckSurfaceCapability(adapter, adapter_format_desc, format_desc, SurfaceType)) + { + TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n"); + return WINED3DERR_NOTAVAILABLE; } - if(Usage & WINED3DUSAGE_DEPTHSTENCIL) { - if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) + if (Usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; + } + + if (Usage & WINED3DUSAGE_RENDERTARGET) + { + if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_RENDERTARGET; + } + + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + break; + + case WINED3DRTYPE_TEXTURE: + /* Texture allows: + * - WINED3DUSAGE_AUTOGENMIPMAP + * - WINED3DUSAGE_DEPTHSTENCIL + * - WINED3DUSAGE_DMAP + * - WINED3DUSAGE_DYNAMIC + * - WINED3DUSAGE_NONSECURE (d3d9ex) + * - WINED3DUSAGE_RENDERTARGET + * - WINED3DUSAGE_SOFTWAREPROCESSING + * - WINED3DUSAGE_TEXTAPI (d3d9ex) + * - WINED3DUSAGE_QUERY_WRAPANDMIP + */ + if (SurfaceType != SURFACE_OPENGL) + { + TRACE_(d3d_caps)("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!CheckTextureCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) + { + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + /* When autogenmipmap isn't around continue and return + * WINED3DOK_NOAUTOGEN instead of D3D_OK. */ + TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n"); + else + UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP; + } + + /* Always report dynamic locking. */ + if (Usage & WINED3DUSAGE_DYNAMIC) + UsageCaps |= WINED3DUSAGE_DYNAMIC; + + if (Usage & WINED3DUSAGE_RENDERTARGET) + { + if (!CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_RENDERTARGET; + } + + /* Always report software processing. */ + if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING) + UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; + + if (Usage & WINED3DUSAGE_QUERY_FILTER) + { + if (!CheckFilterCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_FILTER; + } + + if (Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) + { + if (!CheckBumpMapCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP; + } + + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + + if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) + { + if (!CheckSrgbReadCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; + } + + if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE) + { + if (!CheckSrgbWriteCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; + } + + if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) + { + if (!CheckVertexTextureCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; + } + + if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) + { + if (!CheckWrapAndMipCapability(adapter, format_desc)) + { + TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; + } + + if (Usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (!CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc)) { - UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; - } else { TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n"); return WINED3DERR_NOTAVAILABLE; } + if ((format_desc->Flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW]) + { + TRACE_(d3d_caps)("[FAILED] - No shadow sampler support.\n"); + return WINED3DERR_NOTAVAILABLE; + } + UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; } - } else { - TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n"); - return WINED3DERR_NOTAVAILABLE; - } - } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) { - /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented. - * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too. - * - * Volumetexture allows: - * - D3DUSAGE_DYNAMIC - * - D3DUSAGE_NONSECURE (d3d9ex) - * - D3DUSAGE_SOFTWAREPROCESSING - * - D3DUSAGE_QUERY_WRAPANDMIP - */ + break; - if(SurfaceType != SURFACE_OPENGL) { - TRACE("[FAILED]\n"); - return WINED3DERR_NOTAVAILABLE; - } + case WINED3DRTYPE_VOLUMETEXTURE: + case WINED3DRTYPE_VOLUME: + /* Volume is to VolumeTexture what Surface is to Texture, but its + * usage caps are not documented. Most driver seem to offer + * (nearly) the same on Volume and VolumeTexture, so do that too. + * + * Volumetexture allows: + * - D3DUSAGE_DYNAMIC + * - D3DUSAGE_NONSECURE (d3d9ex) + * - D3DUSAGE_SOFTWAREPROCESSING + * - D3DUSAGE_QUERY_WRAPANDMIP + */ + if (SurfaceType != SURFACE_OPENGL) + { + TRACE_(d3d_caps)("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } - /* Check volume texture and volume usage caps */ - if (gl_info->supported[EXT_TEXTURE3D]) - { - if (!CheckTextureCapability(adapter, DeviceType, format_desc)) + if (!gl_info->supported[EXT_TEXTURE3D]) + { + TRACE_(d3d_caps)("[FAILED] - No volume texture support\n"); + return WINED3DERR_NOTAVAILABLE; + } + + if (!CheckTextureCapability(adapter, format_desc)) { TRACE_(d3d_caps)("[FAILED] - Format not supported\n"); return WINED3DERR_NOTAVAILABLE; } - /* Always report dynamic locking */ - if(Usage & WINED3DUSAGE_DYNAMIC) + /* Filter formats that need conversion; For one part, this + * conversion is unimplemented, and volume textures are huge, so + * it would be a big performance hit. Unless we hit an application + * needing one of those formats, don't advertize them to avoid + * leading applications into temptation. The windows drivers don't + * support most of those formats on volumes anyway, except for + * WINED3DFMT_R32_FLOAT. */ + switch (CheckFormat) + { + case WINED3DFMT_P8_UINT: + case WINED3DFMT_L4A4_UNORM: + case WINED3DFMT_R32_FLOAT: + case WINED3DFMT_R16_FLOAT: + case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: + case WINED3DFMT_R5G5_SNORM_L6_UNORM: + case WINED3DFMT_R16G16_UNORM: + TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); + return WINED3DERR_NOTAVAILABLE; + + case WINED3DFMT_R8G8B8A8_SNORM: + case WINED3DFMT_R16G16_SNORM: + if (!gl_info->supported[NV_TEXTURE_SHADER]) + { + TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); + return WINED3DERR_NOTAVAILABLE; + } + break; + + case WINED3DFMT_R8G8_SNORM: + if (!gl_info->supported[NV_TEXTURE_SHADER]) + { + TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); + return WINED3DERR_NOTAVAILABLE; + } + break; + + case WINED3DFMT_DXT1: + case WINED3DFMT_DXT2: + case WINED3DFMT_DXT3: + case WINED3DFMT_DXT4: + case WINED3DFMT_DXT5: + /* The GL_EXT_texture_compression_s3tc spec requires that + * loading an s3tc compressed texture results in an error. + * While the D3D refrast does support s3tc volumes, at + * least the nvidia windows driver does not, so we're free + * not to support this format. */ + TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n"); + return WINED3DERR_NOTAVAILABLE; + + default: + /* Do nothing, continue with checking the format below */ + break; + } + + /* Always report dynamic locking. */ + if (Usage & WINED3DUSAGE_DYNAMIC) UsageCaps |= WINED3DUSAGE_DYNAMIC; - /* Always report software processing */ - if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING) + /* Always report software processing. */ + if (Usage & WINED3DUSAGE_SOFTWAREPROCESSING) UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING; - /* Check QUERY_FILTER support */ - if(Usage & WINED3DUSAGE_QUERY_FILTER) { - if (CheckFilterCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_FILTER) + { + if (!CheckFilterCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_FILTER; - } else { TRACE_(d3d_caps)("[FAILED] - No query filter support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_FILTER; } - /* Check QUERY_POSTPIXELSHADER_BLENDING support */ - if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { - if (CheckPostPixelShaderBlendingCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) + { + if (!CheckPostPixelShaderBlendingCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; - } else { TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; } - /* Check QUERY_SRGBREAD support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) { - if (CheckSrgbReadCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) + { + if (!CheckSrgbReadCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD; } - /* Check QUERY_SRGBWRITE support */ - if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) { - if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_SRGBWRITE) + { + if (!CheckSrgbWriteCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; - } else { TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE; } - /* Check QUERY_VERTEXTEXTURE support */ - if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) { - if (CheckVertexTextureCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) + { + if (!CheckVertexTextureCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; - } else { TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE; } - /* Check QUERY_WRAPANDMIP support */ - if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) { - if (CheckWrapAndMipCapability(adapter, format_desc)) + if (Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) + { + if (!CheckWrapAndMipCapability(adapter, format_desc)) { - UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; - } else { TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n"); return WINED3DERR_NOTAVAILABLE; } + UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP; } - } else { - TRACE_(d3d_caps)("[FAILED] - No volume texture support\n"); + break; + + default: + FIXME_(d3d_caps)("Unhandled resource type %s.\n", debug_d3dresourcetype(RType)); return WINED3DERR_NOTAVAILABLE; - } - - /* Filter formats that need conversion; For one part, this conversion is unimplemented, - * and volume textures are huge, so it would be a big performance hit. Unless we hit an - * app needing one of those formats, don't advertize them to avoid leading apps into - * temptation. The windows drivers don't support most of those formats on volumes anyway, - * except of R32F. - */ - switch(CheckFormat) { - case WINED3DFMT_P8_UINT: - case WINED3DFMT_L4A4_UNORM: - case WINED3DFMT_R32_FLOAT: - case WINED3DFMT_R16_FLOAT: - case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: - case WINED3DFMT_R5G5_SNORM_L6_UNORM: - case WINED3DFMT_R16G16_UNORM: - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return WINED3DERR_NOTAVAILABLE; - - case WINED3DFMT_R8G8B8A8_SNORM: - case WINED3DFMT_R16G16_SNORM: - if (!gl_info->supported[NV_TEXTURE_SHADER]) - { - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return WINED3DERR_NOTAVAILABLE; - } - break; - - case WINED3DFMT_R8G8_SNORM: - if (!gl_info->supported[NV_TEXTURE_SHADER]) - { - TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n"); - return WINED3DERR_NOTAVAILABLE; - } - break; - - case WINED3DFMT_DXT1: - case WINED3DFMT_DXT2: - case WINED3DFMT_DXT3: - case WINED3DFMT_DXT4: - case WINED3DFMT_DXT5: - /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc - * compressed texture results in an error. While the D3D refrast does - * support s3tc volumes, at least the nvidia windows driver does not, so - * we're free not to support this format. - */ - TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n"); - return WINED3DERR_NOTAVAILABLE; - - default: - /* Do nothing, continue with checking the format below */ - break; - } - } else if(RType == WINED3DRTYPE_BUFFER){ - /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */ - TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n"); - return WINED3DERR_NOTAVAILABLE; } - /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which - * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other - * usage flags match. */ - if(UsageCaps == Usage) { + /* When the UsageCaps exactly matches Usage return WINED3D_OK except for + * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then + * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */ + if (UsageCaps == Usage) return WINED3D_OK; - } else if((UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) && (Usage & WINED3DUSAGE_AUTOGENMIPMAP)){ + if (UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) return WINED3DOK_NOAUTOGEN; - } else { - TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested for CheckFormat=%s and RType=%d but only %#08x is available\n", Usage, debug_d3dformat(CheckFormat), RType, UsageCaps); - return WINED3DERR_NOTAVAILABLE; - } + + TRACE_(d3d_caps)("[FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available\n", + Usage, debug_d3dformat(CheckFormat), debug_d3dresourcetype(RType), UsageCaps); + + return WINED3DERR_NOTAVAILABLE; } static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT adapter_idx, @@ -4204,13 +4223,14 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING; /* TODO: WINED3DPMISCCAPS_NULLREFERENCE - WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS WINED3DPMISCCAPS_FOGANDSPECULARALPHA WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS WINED3DPMISCCAPS_FOGVERTEXCLAMPED */ if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE]) pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND; + if (gl_info->supported[EXT_DRAW_BUFFERS2]) + pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS; pCaps->RasterCaps = WINED3DPRASTERCAPS_DITHER | WINED3DPRASTERCAPS_PAT | @@ -4517,10 +4537,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DPTFILTERCAPS_MAGFLINEAR; pCaps->VertexTextureFilterCaps = 0; - memset(&shader_caps, 0, sizeof(shader_caps)); adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps); - - memset(&fragment_caps, 0, sizeof(fragment_caps)); adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps); /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */ @@ -4551,13 +4568,6 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages; pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures; - pCaps->VS20Caps = shader_caps.VS20Caps; - pCaps->MaxVShaderInstructionsExecuted = shader_caps.MaxVShaderInstructionsExecuted; - pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots; - pCaps->PS20Caps = shader_caps.PS20Caps; - pCaps->MaxPShaderInstructionsExecuted = shader_caps.MaxPShaderInstructionsExecuted; - pCaps->MaxPixelShader30InstructionSlots = shader_caps.MaxPixelShader30InstructionSlots; - /* The following caps are shader specific, but they are things we cannot detect, or which * are the same among all shader models. So to avoid code duplication set the shader version * specific, but otherwise constant caps here @@ -4959,7 +4969,7 @@ static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info) } } -BOOL InitAdapters(IWineD3DImpl *This) +static BOOL InitAdapters(IWineD3DImpl *This) { static HMODULE mod_gl; BOOL ret; @@ -5120,17 +5130,6 @@ BOOL InitAdapters(IWineD3DImpl *This) cfgs->doubleBuffer = values[9]; cfgs->auxBuffers = values[10]; - cfgs->pbufferDrawable = FALSE; - /* Check for pbuffer support when it is around as - * wglGetPixelFormatAttribiv fails for unknown attributes. */ - if (gl_info->supported[WGL_ARB_PBUFFER]) - { - int attrib = WGL_DRAW_TO_PBUFFER_ARB; - int value; - if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value))) - cfgs->pbufferDrawable = value; - } - cfgs->numSamples = 0; /* Check multisample support */ if (gl_info->supported[ARB_MULTISAMPLE]) @@ -5145,7 +5144,11 @@ BOOL InitAdapters(IWineD3DImpl *This) } } - TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, samples=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable, cfgs->pbufferDrawable); + TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " + "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n", + cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, + cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, + cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable); cfgs++; } } @@ -5182,14 +5185,17 @@ BOOL InitAdapters(IWineD3DImpl *This) cfgs->colorSize = ppfd.cColorBits; cfgs->depthSize = ppfd.cDepthBits; cfgs->stencilSize = ppfd.cStencilBits; - cfgs->pbufferDrawable = 0; cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0; cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB; cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0; cfgs->auxBuffers = ppfd.cAuxBuffers; cfgs->numSamples = 0; - TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable); + TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, " + "depth=%d, stencil=%d, windowDrawable=%d\n", + cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, + cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, + cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable); cfgs++; adapter->nCfgs++; } @@ -5261,7 +5267,7 @@ nogl_adapter: * IWineD3D VTbl follows **********************************************************/ -const IWineD3DVtbl IWineD3D_Vtbl = +static const struct IWineD3DVtbl IWineD3D_Vtbl = { /* IUnknown */ IWineD3DImpl_QueryInterface, @@ -5291,3 +5297,23 @@ const struct wined3d_parent_ops wined3d_null_parent_ops = { wined3d_null_wined3d_object_destroyed, }; + +HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent) +{ + wined3d->lpVtbl = &IWineD3D_Vtbl; + wined3d->dxVersion = version; + wined3d->ref = 1; + wined3d->parent = parent; + + if (!InitAdapters(wined3d)) + { + WARN("Failed to initialize adapters.\n"); + if (version > 7) + { + MESSAGE("Direct3D%u is not available without OpenGL.\n", version); + return E_FAIL; + } + } + + return WINED3D_OK; +} diff --git a/dll/directx/wine/wined3d/drawprim.c b/dll/directx/wine/wined3d/drawprim.c index b29d012b9d1..b36ef5b49ae 100644 --- a/dll/directx/wine/wined3d/drawprim.c +++ b/dll/directx/wine/wined3d/drawprim.c @@ -28,7 +28,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); -#define GLINFO_LOCATION This->adapter->gl_info #include #include @@ -71,7 +70,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context UINT vx_index; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const UINT *streamOffset = This->stateBlock->streamOffset; - long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; + LONG SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; BOOL pixelShader = use_ps(This->stateBlock); BOOL specular_fog = FALSE; const BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; @@ -85,14 +84,14 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context TRACE("Using slow vertex array code\n"); /* Variable Initialization */ - if (idxSize != 0) { - /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer. - * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing - * idxData will be != NULL - */ - if(idxData == NULL) { - idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData); - } + if (idxSize) + { + /* Immediate mode drawing can't make use of indices in a vbo - get the + * data from the index buffer. If the index buffer has no vbo (not + * supported or other reason), or with user pointer drawing idxData + * will be non-NULL. */ + if (!idxData) + idxData = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->pIndexData, gl_info); if (idxSize == 2) pIdxBufS = idxData; else pIdxBufL = idxData; @@ -102,7 +101,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context } /* Start drawing in GL */ - VTRACE(("glBegin(%x)\n", glPrimType)); glBegin(glPrimType); if (si->use_map & (1 << WINED3D_FFP_POSITION)) @@ -226,13 +224,10 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context if (idxData != NULL) { /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) { - VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufS[startIdx+vx_index])); + if (idxSize == 2) SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex; - } else { - VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufL[startIdx+vx_index])); + else SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex; - } } tmp_tex_mask = tex_mask; @@ -426,7 +421,8 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT startIdx) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - long SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + LONG SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex; const WORD *pIdxBufS = NULL; const DWORD *pIdxBufL = NULL; UINT vx_index; @@ -434,14 +430,14 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream IWineD3DStateBlockImpl *stateblock = This->stateBlock; const BYTE *ptr; - if (idxSize != 0) { - /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer. - * If the index buffer has no vbo(not supported or other reason), or with user pointer drawing - * idxData will be != NULL - */ - if(idxData == NULL) { - idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData); - } + if (idxSize) + { + /* Immediate mode drawing can't make use of indices in a vbo - get the + * data from the index buffer. If the index buffer has no vbo (not + * supported or other reason), or with user pointer drawing idxData + * will be non-NULL. */ + if (!idxData) + idxData = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->pIndexData, gl_info); if (idxSize == 2) pIdxBufS = idxData; else pIdxBufL = idxData; @@ -451,20 +447,16 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream } /* Start drawing in GL */ - VTRACE(("glBegin(%x)\n", glPrimitiveType)); glBegin(glPrimitiveType); for (vx_index = 0; vx_index < numberOfVertices; ++vx_index) { if (idxData != NULL) { /* Indexed so work out the number of strides to skip */ - if (idxSize == 2) { - VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index])); + if (idxSize == 2) SkipnStrides = pIdxBufS[startIdx + vx_index] + stateblock->loadBaseVertexIndex; - } else { - VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index])); + else SkipnStrides = pIdxBufL[startIdx + vx_index] + stateblock->loadBaseVertexIndex; - } } for (i = MAX_ATTRIBS - 1; i >= 0; i--) @@ -543,7 +535,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine { struct wined3d_buffer *vb = (struct wined3d_buffer *)stateblock->streamSource[si->elements[instancedData[j]].stream_idx]; - ptr += (long) buffer_get_sysmem(vb); + ptr += (ULONG_PTR)buffer_get_sysmem(vb, &This->adapter->gl_info); } send_attribute(This, si->elements[instancedData[j]].format_desc->format, instancedData[j], ptr); @@ -555,7 +547,8 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine } } -static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_info *s) +static inline void remove_vbos(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info, + struct wined3d_stream_info *s) { unsigned int i; @@ -570,7 +563,7 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_i { struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; e->buffer_object = 0; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); + e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, gl_info)); } } } @@ -580,7 +573,6 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DSurfaceImpl *target; struct wined3d_context *context; unsigned int i; @@ -591,11 +583,11 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Invalidate the back buffer memory so LockRect will read it the next time */ for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i) { - target = (IWineD3DSurfaceImpl *)This->render_targets[i]; + IWineD3DSurface *target = (IWineD3DSurface *)This->render_targets[i]; if (target) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL); - IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_LoadLocation(target, SFLAG_INDRAWABLE, NULL); + IWineD3DSurface_ModifyLocation(target, SFLAG_INDRAWABLE, TRUE); } } } @@ -603,9 +595,18 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Signals other modules that a drawing is in progress and the stateblock finalized */ This->isInDraw = TRUE; - context = context_acquire(This, This->render_targets[0], CTXUSAGE_DRAWPRIM); + context = context_acquire(This, This->render_targets[0]); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping draw.\n"); + return; + } - if (This->stencilBufferTarget) { + context_apply_draw_state(context, This); + + if (This->depth_stencil) + { /* Note that this depends on the context_acquire() call above to set * This->render_offscreen properly. We don't currently take the * Z-compare function into account, but we could skip loading the @@ -614,9 +615,33 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE] || This->stateBlock->renderState[WINED3DRS_ZENABLE]) - surface_load_ds_location(This->stencilBufferTarget, context, location); - if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) - surface_modify_ds_location(This->stencilBufferTarget, location); + { + RECT current_rect, draw_rect, r; + + if (location == SFLAG_DS_ONSCREEN && This->depth_stencil != This->onscreen_depth_stencil) + device_switch_onscreen_ds(This, context, This->depth_stencil); + + if (This->depth_stencil->Flags & location) + SetRect(¤t_rect, 0, 0, + This->depth_stencil->ds_current_size.cx, + This->depth_stencil->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + device_get_draw_rect(This, &draw_rect); + + IntersectRect(&r, &draw_rect, ¤t_rect); + if (!EqualRect(&r, &draw_rect)) + surface_load_ds_location(This->depth_stencil, context, location); + + if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) + { + surface_modify_ds_location(This->depth_stencil, location, + This->depth_stencil->ds_current_size.cx, + This->depth_stencil->ds_current_size.cy); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->depth_stencil, SFLAG_INDRAWABLE, TRUE); + } + } } /* Ok, we will be updating the screen from here onwards so grab the lock */ @@ -659,7 +684,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT if(emulation) { stream_info = &stridedlcl; memcpy(&stridedlcl, &This->strided_streams, sizeof(stridedlcl)); - remove_vbos(This, &stridedlcl); + remove_vbos(This, context->gl_info, &stridedlcl); } } @@ -691,7 +716,12 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Finished updating the screen, restore lock */ LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + for(i = 0; i < This->num_buffer_queries; i++) + { + wined3d_event_query_issue(This->buffer_queries[i], This); + } + + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); @@ -700,14 +730,14 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT /* Diagnostics */ #ifdef SHOW_FRAME_MAKEUP { - static long int primCounter = 0; + static LONG primCounter = 0; /* NOTE: set primCounter to the value reported by drawprim before you want to to write frame makeup to /tmp */ if (primCounter >= 0) { WINED3DLOCKED_RECT r; char buffer[80]; IWineD3DSurface_LockRect(This->render_targets[0], &r, NULL, WINED3DLOCK_READONLY); - sprintf(buffer, "/tmp/backbuffer_%ld.tga", primCounter); + sprintf(buffer, "/tmp/backbuffer_%d.tga", primCounter); TRACE("Saving screenshot %s\n", buffer); IWineD3DSurface_SaveSnapshot(This->render_targets[0], buffer); IWineD3DSurface_UnlockRect(This->render_targets[0]); @@ -718,7 +748,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT int textureNo; for (textureNo = 0; textureNo < MAX_COMBINED_SAMPLERS; ++textureNo) { if (This->stateBlock->textures[textureNo] != NULL) { - sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo); + sprintf(buffer, "/tmp/texture_%p_%d_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo); TRACE("Saving texture %s\n", buffer); if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) { IWineD3DTexture_GetSurfaceLevel(This->stateBlock->textures[textureNo], 0, &pSur); @@ -732,7 +762,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT } #endif } - TRACE("drawprim #%ld\n", primCounter); + TRACE("drawprim #%d\n", primCounter); ++primCounter; } #endif @@ -788,7 +818,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, /* Simply activate the context for blitting. This disables all the things we don't want and * takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the * patch (as opposed to normal draws) will most likely need different changes anyway. */ - context = context_acquire(This, NULL, CTXUSAGE_BLIT); + context = context_acquire(This, NULL); + context_apply_blit_state(context, This); /* First, locate the position data. This is provided in a vertex buffer in the stateblock. * Beware of vbos @@ -800,7 +831,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, { struct wined3d_buffer *vb; vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); + e->data = (BYTE *)((ULONG_PTR)e->data + (ULONG_PTR)buffer_get_sysmem(vb, context->gl_info)); } vtxStride = e->stride; data = e->data + diff --git a/dll/directx/wine/wined3d/glsl_shader.c b/dll/directx/wine/wined3d/glsl_shader.c index cb23ee6aa0e..056e9adb45a 100644 --- a/dll/directx/wine/wined3d/glsl_shader.c +++ b/dll/directx/wine/wined3d/glsl_shader.c @@ -39,8 +39,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_constants); WINE_DECLARE_DEBUG_CHANNEL(d3d_caps); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - #define WINED3D_GLSL_SAMPLE_PROJECTED 0x1 #define WINED3D_GLSL_SAMPLE_RECT 0x2 #define WINED3D_GLSL_SAMPLE_LOD 0x4 @@ -89,7 +87,8 @@ struct shader_glsl_priv { struct constant_heap vconst_heap; struct constant_heap pconst_heap; unsigned char *stack; - GLhandleARB depth_blt_program[tex_type_count]; + GLhandleARB depth_blt_program_full[tex_type_count]; + GLhandleARB depth_blt_program_masked[tex_type_count]; UINT next_constant_version; }; @@ -255,7 +254,7 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA /* GL locking is done by the caller. */ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program) { - GLint i, object_count, source_size; + GLint i, object_count, source_size = -1; GLhandleARB *objects; char *source = NULL; @@ -275,7 +274,7 @@ static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_inf GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp)); - if (!source || source_size < tmp) + if (source_size < tmp) { HeapFree(GetProcessHeap(), 0, source); @@ -719,8 +718,8 @@ static void shader_glsl_load_np2fixup_constants( static void shader_glsl_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; + IWineD3DDeviceImpl *device = context->swapchain->device; IWineD3DStateBlockImpl* stateBlock = device->stateBlock; struct shader_glsl_priv *priv = device->shader_priv; @@ -807,7 +806,7 @@ static void shader_glsl_load_constants(const struct wined3d_context *context, correction_params[1] = 1.0f; } else { /* position is window relative, not viewport relative */ - correction_params[0] = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height; + correction_params[0] = context->current_rt->currentDesc.Height; correction_params[1] = -1.0f; } GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params)); @@ -1034,7 +1033,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont */ FIXME("Cannot find a free uniform for vpos correction params\n"); shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n", - context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height, + context->render_offscreen ? 0.0f : device->render_targets[0]->currentDesc.Height, context->render_offscreen ? 1.0f : -1.0f); } shader_addline(buffer, "vec4 vpos;\n"); @@ -1048,20 +1047,37 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont switch (reg_maps->sampler_type[i]) { case WINED3DSTT_1D: - shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i); + if (pshader && ps_args->shadow & (1 << i)) + shader_addline(buffer, "uniform sampler1DShadow %csampler%u;\n", prefix, i); + else + shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i); break; case WINED3DSTT_2D: - if(device->stateBlock->textures[i] && - IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) == GL_TEXTURE_RECTANGLE_ARB) { - shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i); - } else { - shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); + if (pshader && ps_args->shadow & (1 << i)) + { + if (device->stateBlock->textures[i] + && IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) + == GL_TEXTURE_RECTANGLE_ARB) + shader_addline(buffer, "uniform sampler2DRectShadow %csampler%u;\n", prefix, i); + else + shader_addline(buffer, "uniform sampler2DShadow %csampler%u;\n", prefix, i); + } + else + { + if (device->stateBlock->textures[i] + && IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) + == GL_TEXTURE_RECTANGLE_ARB) + shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i); + else + shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); } break; case WINED3DSTT_CUBE: + if (pshader && ps_args->shadow & (1 << i)) FIXME("Unsupported Cube shadow sampler.\n"); shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i); break; case WINED3DSTT_VOLUME: + if (pshader && ps_args->shadow & (1 << i)) FIXME("Unsupported 3D shadow sampler.\n"); shader_addline(buffer, "uniform sampler3D %csampler%u;\n", prefix, i); break; default: @@ -1642,9 +1658,13 @@ static inline const char *shader_get_comp_op(DWORD op) } } -static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_info, - DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function) +static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx, + DWORD sampler_idx, DWORD flags, glsl_sample_function_t *sample_function) { + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ctx->reg_maps->sampler_type[sampler_idx]; + const struct wined3d_gl_info *gl_info = ctx->gl_info; + BOOL shadow = shader_is_pshader_version(ctx->reg_maps->shader_version.type) + && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx)); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT; BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD; @@ -1653,115 +1673,225 @@ static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_inf /* Note that there's no such thing as a projected cube texture. */ switch(sampler_type) { case WINED3DSTT_1D: - if(lod) { - sample_function->name = projected ? "texture1DProjLod" : "texture1DLod"; - } - else if (grad) + if (shadow) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB"; + if (lod) + { + sample_function->name = projected ? "shadow1DProjLod" : "shadow1DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "shadow1DProjGrad" : "shadow1DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "shadow1DProjGradARB" : "shadow1DGradARB"; + else + { + FIXME("Unsupported 1D shadow grad function.\n"); + sample_function->name = "unsupported1DGrad"; + } + } else { - FIXME("Unsupported 1D grad function.\n"); - sample_function->name = "unsupported1DGrad"; + sample_function->name = projected ? "shadow1DProj" : "shadow1D"; } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; } else { - sample_function->name = projected ? "texture1DProj" : "texture1D"; + if (lod) + { + sample_function->name = projected ? "texture1DProjLod" : "texture1DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB"; + else + { + FIXME("Unsupported 1D grad function.\n"); + sample_function->name = "unsupported1DGrad"; + } + } + else + { + sample_function->name = projected ? "texture1DProj" : "texture1D"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0; break; + case WINED3DSTT_2D: - if(texrect) { - if(lod) { - sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod"; - } - else if (grad) + if (shadow) + { + if (texrect) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB"; + if (lod) + { + sample_function->name = projected ? "shadow2DRectProjLod" : "shadow2DRectLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "shadow2DRectProjGrad" : "shadow2DRectGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB"; + else + { + FIXME("Unsupported RECT shadow grad function.\n"); + sample_function->name = "unsupported2DRectGrad"; + } + } else { - FIXME("Unsupported RECT grad function.\n"); - sample_function->name = "unsupported2DRectGrad"; + sample_function->name = projected ? "shadow2DRectProj" : "shadow2DRect"; } } else { - sample_function->name = projected ? "texture2DRectProj" : "texture2DRect"; - } - } else { - if(lod) { - sample_function->name = projected ? "texture2DProjLod" : "texture2DLod"; - } - else if (grad) - { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB"; + if (lod) + { + sample_function->name = projected ? "shadow2DProjLod" : "shadow2DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "shadow2DProjGrad" : "shadow2DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "shadow2DProjGradARB" : "shadow2DGradARB"; + else + { + FIXME("Unsupported 2D shadow grad function.\n"); + sample_function->name = "unsupported2DGrad"; + } + } else { - FIXME("Unsupported 2D grad function.\n"); - sample_function->name = "unsupported2DGrad"; + sample_function->name = projected ? "shadow2DProj" : "shadow2D"; } } - else - { - sample_function->name = projected ? "texture2DProj" : "texture2D"; - } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; + } + else + { + if (texrect) + { + if (lod) + { + sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB"; + else + { + FIXME("Unsupported RECT grad function.\n"); + sample_function->name = "unsupported2DRectGrad"; + } + } + else + { + sample_function->name = projected ? "texture2DRectProj" : "texture2DRect"; + } + } + else + { + if (lod) + { + sample_function->name = projected ? "texture2DProjLod" : "texture2DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB"; + else + { + FIXME("Unsupported 2D grad function.\n"); + sample_function->name = "unsupported2DGrad"; + } + } + else + { + sample_function->name = projected ? "texture2DProj" : "texture2D"; + } + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; break; + case WINED3DSTT_CUBE: - if(lod) { - sample_function->name = "textureCubeLod"; - } - else if (grad) + if (shadow) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = "textureCubeGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = "textureCubeGradARB"; - else - { - FIXME("Unsupported Cube grad function.\n"); - sample_function->name = "unsupportedCubeGrad"; - } + FIXME("Unsupported Cube shadow function.\n "); + sample_function->name = "unsupportedCubeShadow"; + sample_function->coord_mask = 0; } else { - sample_function->name = "textureCube"; + if (lod) + { + sample_function->name = "textureCubeLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = "textureCubeGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = "textureCubeGradARB"; + else + { + FIXME("Unsupported Cube grad function.\n"); + sample_function->name = "unsupportedCubeGrad"; + } + } + else + { + sample_function->name = "textureCube"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; break; + case WINED3DSTT_VOLUME: - if(lod) { - sample_function->name = projected ? "texture3DProjLod" : "texture3DLod"; - } - else if (grad) + if (shadow) { - if (gl_info->supported[EXT_GPU_SHADER4]) - sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad"; - else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) - sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB"; - else - { - FIXME("Unsupported 3D grad function.\n"); - sample_function->name = "unsupported3DGrad"; - } + FIXME("Unsupported 3D shadow function.\n "); + sample_function->name = "unsupported3DShadow"; + sample_function->coord_mask = 0; } else { - sample_function->name = projected ? "texture3DProj" : "texture3D"; + if (lod) + { + sample_function->name = projected ? "texture3DProjLod" : "texture3DLod"; + } + else if (grad) + { + if (gl_info->supported[EXT_GPU_SHADER4]) + sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad"; + else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) + sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB"; + else + { + FIXME("Unsupported 3D grad function.\n"); + sample_function->name = "unsupported3DGrad"; + } + } + else + { + sample_function->name = projected ? "texture3DProj" : "texture3D"; + } + sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; } - sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; break; + default: sample_function->name = ""; sample_function->coord_mask = 0; @@ -2164,16 +2294,26 @@ static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins) { struct wined3d_shader_buffer *buffer = ins->ctx->buffer; glsl_src_param_t src_param; + unsigned int mask_size; DWORD write_mask; char dst_mask[6]; write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask); + mask_size = shader_glsl_get_write_mask_size(write_mask); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param); shader_addline(buffer, "tmp0.x = length(%s);\n", src_param.param_str); shader_glsl_append_dst(buffer, ins); - shader_addline(buffer, "tmp0.x == 0.0 ? (%s * FLT_MAX) : (%s / tmp0.x));", - src_param.param_str, src_param.param_str); + if (mask_size > 1) + { + shader_addline(buffer, "tmp0.x == 0.0 ? vec%u(0.0) : (%s / tmp0.x));\n", + mask_size, src_param.param_str); + } + else + { + shader_addline(buffer, "tmp0.x == 0.0 ? 0.0 : (%s / tmp0.x));\n", + src_param.param_str); + } } /** Process the WINED3DSIO_EXPP instruction in GLSL: @@ -2868,10 +3008,8 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, ins->ctx->reg_maps->shader_version.minor); - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_sample_function_t sample_function; DWORD sample_flags = 0; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type; DWORD sampler_idx; DWORD mask = 0, swizzle; @@ -2879,11 +3017,11 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) * 2.0+: Use provided sampler source. */ if (shader_version < WINED3D_SHADER_VERSION(2,0)) sampler_idx = ins->dst[0].reg.idx; else sampler_idx = ins->src[1].reg.idx; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if (shader_version < WINED3D_SHADER_VERSION(1,4)) { DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ if (flags & WINED3DTTFF_PROJECTED && sampler_type != WINED3DSTT_CUBE) { @@ -2922,7 +3060,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins) sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); mask |= sample_function.coord_mask; if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE; @@ -2960,7 +3098,6 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins) glsl_sample_function_t sample_function; glsl_src_param_t coord_param, dx_param, dy_param; DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD; - DWORD sampler_type; DWORD sampler_idx; DWORD swizzle = ins->src[1].swizzle; @@ -2971,13 +3108,12 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins) } sampler_idx = ins->src[1].reg.idx; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param); shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param); @@ -2994,17 +3130,15 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins) glsl_sample_function_t sample_function; glsl_src_param_t coord_param, lod_param; DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD; - DWORD sampler_type; DWORD sampler_idx; DWORD swizzle = ins->src[1].swizzle; sampler_idx = ins->src[1].reg.idx; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; if(deviceImpl->stateBlock->textures[sampler_idx] && IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { sample_flags |= WINED3D_GLSL_SAMPLE_RECT; } - shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param); @@ -3071,12 +3205,10 @@ static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins) * then perform a 1D texture lookup from stage dstregnum, place into dst. */ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; glsl_sample_function_t sample_function; DWORD sampler_idx = ins->dst[0].reg.idx; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; UINT mask_size; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -3086,7 +3218,7 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) * * It is a dependent read - not valid with conditional NP2 textures */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask); switch(mask_size) @@ -3199,18 +3331,16 @@ static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins) static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; DWORD reg = ins->dst[0].reg.idx; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; glsl_src_param_t src0_param; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy"); @@ -3223,17 +3353,15 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins) DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD reg = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); @@ -3266,13 +3394,11 @@ static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins) static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; DWORD reg = ins->dst[0].reg.idx; glsl_src_param_t src0_param; glsl_src_param_t src1_param; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state; - WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg]; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; glsl_sample_function_t sample_function; @@ -3285,7 +3411,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, stype, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); @@ -3298,13 +3424,11 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; DWORD reg = ins->dst[0].reg.idx; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state; glsl_src_param_t src0_param; DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param); @@ -3318,7 +3442,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n"); /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function); /* Sample the texture using the calculated coordinates */ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz"); @@ -3334,10 +3458,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) { IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_sample_function_t sample_function; glsl_src_param_t coord_param; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type; DWORD sampler_idx; DWORD mask; DWORD flags; @@ -3346,9 +3468,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) sampler_idx = ins->dst[0].reg.idx; flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; - sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); mask = sample_function.coord_mask; shader_glsl_write_mask_to_str(mask, coord_mask); @@ -3407,15 +3528,13 @@ static void shader_glsl_bem(const struct wined3d_shader_instruction *ins) * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "%s.wx", src0_param.reg_name); } @@ -3424,15 +3543,13 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins) * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param); - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "%s.yz", src0_param.reg_name); } @@ -3441,14 +3558,12 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins) * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */ static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins) { - const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; glsl_src_param_t src0_param; DWORD sampler_idx = ins->dst[0].reg.idx; - WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx]; glsl_sample_function_t sample_function; /* Dependent read, not valid with conditional NP2 */ - shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function); + shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, @@ -4453,10 +4568,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context, } /* GL locking is done by the caller */ -static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type) +static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked) { GLhandleARB program_id; GLhandleARB vshader_id, pshader_id; + const char *blt_pshader; + static const char *blt_vshader[] = { "#version 120\n" @@ -4468,7 +4585,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, "}\n" }; - static const char *blt_pshaders[tex_type_count] = + static const char *blt_pshaders_full[tex_type_count] = { /* tex_1d */ NULL, @@ -4498,7 +4615,44 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, "}\n", }; - if (!blt_pshaders[tex_type]) + static const char *blt_pshaders_masked[tex_type_count] = + { + /* tex_1d */ + NULL, + /* tex_2d */ + "#version 120\n" + "uniform sampler2D sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n" + "}\n", + /* tex_3d */ + NULL, + /* tex_cube */ + "#version 120\n" + "uniform samplerCube sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n" + "}\n", + /* tex_rect */ + "#version 120\n" + "#extension GL_ARB_texture_rectangle : enable\n" + "uniform sampler2DRect sampler;\n" + "uniform vec4 mask;\n" + "void main(void)\n" + "{\n" + " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n" + " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n" + "}\n", + }; + + blt_pshader = masked ? blt_pshaders_masked[tex_type] : blt_pshaders_full[tex_type]; + if (!blt_pshader) { FIXME("tex_type %#x not supported\n", tex_type); tex_type = tex_2d; @@ -4509,7 +4663,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, GL_EXTCALL(glCompileShaderARB(vshader_id)); pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); - GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshaders[tex_type], NULL)); + GL_EXTCALL(glShaderSourceARB(pshader_id, 1, &blt_pshader, NULL)); GL_EXTCALL(glCompileShaderARB(pshader_id)); program_id = GL_EXTCALL(glCreateProgramObjectARB()); @@ -4530,8 +4684,8 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, /* GL locking is done by the caller */ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) { - IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; + IWineD3DDeviceImpl *device = context->swapchain->device; struct shader_glsl_priv *priv = device->shader_priv; GLhandleARB program_id = 0; GLenum old_vertex_color_clamp, current_vertex_color_clamp; @@ -4571,21 +4725,34 @@ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS } /* GL locking is done by the caller */ -static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) { +static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, + enum tex_types tex_type, const SIZE *ds_mask_size) +{ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; + BOOL masked = ds_mask_size->cx && ds_mask_size->cy; struct shader_glsl_priv *priv = This->shader_priv; - GLhandleARB *blt_program = &priv->depth_blt_program[tex_type]; + GLhandleARB *blt_program; + GLint loc; - if (!*blt_program) { - GLint loc; - *blt_program = create_glsl_blt_shader(gl_info, tex_type); + blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type]; + if (!*blt_program) + { + *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked); loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler")); GL_EXTCALL(glUseProgramObjectARB(*blt_program)); GL_EXTCALL(glUniform1iARB(loc, 0)); - } else { + } + else + { GL_EXTCALL(glUseProgramObjectARB(*blt_program)); } + + if (masked) + { + loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask")); + GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy)); + } } /* GL locking is done by the caller */ @@ -4625,7 +4792,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { return; } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface) @@ -4644,7 +4811,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { return; } - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface) @@ -4821,9 +4988,13 @@ static void shader_glsl_free(IWineD3DDevice *iface) { ENTER_GL(); for (i = 0; i < tex_type_count; ++i) { - if (priv->depth_blt_program[i]) + if (priv->depth_blt_program_full[i]) { - GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i])); + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i])); + } + if (priv->depth_blt_program_masked[i]) + { + GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i])); } } LEAVE_GL(); diff --git a/dll/directx/wine/wined3d/nvidia_texture_shader.c b/dll/directx/wine/wined3d/nvidia_texture_shader.c index 64bb883d6c8..24cba329f20 100644 --- a/dll/directx/wine/wined3d/nvidia_texture_shader.c +++ b/dll/directx/wine/wined3d/nvidia_texture_shader.c @@ -28,8 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION stateblock->device->adapter->gl_info - /* GL locking for state handlers is done by the caller. */ static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -137,7 +135,6 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX GLenum portion = is_alpha ? GL_ALPHA : GL_RGB; GLenum target = GL_COMBINER0_NV + stage; GLenum output; - IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* For GLINFO_LOCATION */ TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx); @@ -579,6 +576,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); DWORD mapped_stage = stateblock->device->texUnitMap[stage + 1]; + const struct wined3d_gl_info *gl_info = context->gl_info; float mat[2][2]; /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to @@ -587,7 +585,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix * for stage + 1. Keep the nvrc tex unit mapping in mind too */ - if (mapped_stage < context->gl_info->limits.textures) + if (mapped_stage < gl_info->limits.textures) { GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage))"); @@ -606,6 +604,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0])); @@ -629,6 +628,15 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) { static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps) { + pCaps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; + + /* The caps below can be supported but aren't handled yet in utils.c + * 'd3dta_to_combiner_input', disable them until support is fixed */ +#if 0 + if (gl_info->supported[NV_REGISTER_COMBINERS2]) + pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT; +#endif + pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD | WINED3DTEXOPCAPS_ADDSIGNED | WINED3DTEXOPCAPS_ADDSIGNED2X | @@ -672,14 +680,6 @@ static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct pCaps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners); pCaps->MaxSimultaneousTextures = gl_info->limits.textures; - - pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP; - - /* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */ -#if 0 - if (gl_info->supported[NV_REGISTER_COMBINERS2]) - pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT; -#endif } static HRESULT nvrc_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } @@ -713,119 +713,119 @@ static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup) static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), nvrc_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, NV_TEXTURE_SHADER2 }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), nvrc_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), nvts_texdim }, NV_TEXTURE_SHADER2 }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), nvts_texdim }, NV_TEXTURE_SHADER2 }, diff --git a/dll/directx/wine/wined3d/palette.c b/dll/directx/wine/wined3d/palette.c index 553a08a787b..3fd8be9dd10 100644 --- a/dll/directx/wine/wined3d/palette.c +++ b/dll/directx/wine/wined3d/palette.c @@ -74,7 +74,8 @@ static ULONG WINAPI IWineD3DPaletteImpl_Release(IWineD3DPalette *iface) { } /* Not called from the vtable */ -DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) { +static DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) +{ switch (dwFlags & SIZE_BITS) { case WINEDDPCAPS_1BIT: return 2; case WINEDDPCAPS_2BIT: return 4; @@ -183,7 +184,7 @@ static HRESULT WINAPI IWineD3DPaletteImpl_GetParent(IWineD3DPalette *iface, IUn return WINED3D_OK; } -const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl = +static const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl = { /*** IUnknown ***/ IWineD3DPaletteImpl_QueryInterface, @@ -195,3 +196,33 @@ const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl = IWineD3DPaletteImpl_GetCaps, IWineD3DPaletteImpl_SetEntries }; + +HRESULT wined3d_palette_init(IWineD3DPaletteImpl *palette, IWineD3DDeviceImpl *device, + DWORD flags, const PALETTEENTRY *entries, IUnknown *parent) +{ + HRESULT hr; + + palette->lpVtbl = &IWineD3DPalette_Vtbl; + palette->ref = 1; + palette->parent = parent; + palette->device = device; + palette->Flags = flags; + + palette->palNumEntries = IWineD3DPaletteImpl_Size(flags); + palette->hpal = CreatePalette((const LOGPALETTE *)&palette->palVersion); + if (!palette->hpal) + { + WARN("Failed to create palette.\n"); + return E_FAIL; + } + + hr = IWineD3DPalette_SetEntries((IWineD3DPalette *)palette, 0, 0, IWineD3DPaletteImpl_Size(flags), entries); + if (FAILED(hr)) + { + WARN("Failed to set palette entries, hr %#x.\n", hr); + DeleteObject(palette->hpal); + return hr; + } + + return WINED3D_OK; +} diff --git a/dll/directx/wine/wined3d/query.c b/dll/directx/wine/wined3d/query.c index 3860e2c95b5..b3c77eae692 100644 --- a/dll/directx/wine/wined3d/query.c +++ b/dll/directx/wine/wined3d/query.c @@ -25,33 +25,19 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) -static HRESULT wined3d_event_query_init(const struct wined3d_gl_info *gl_info, struct wined3d_event_query **query) +BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) { - struct wined3d_event_query *ret; - *query = NULL; - if (!gl_info->supported[ARB_SYNC] && !gl_info->supported[NV_FENCE] - && !gl_info->supported[APPLE_FENCE]) return E_NOTIMPL; - - ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); - if (!ret) - { - ERR("Failed to allocate a wined3d event query structure.\n"); - return E_OUTOFMEMORY; - } - ret->context = NULL; - *query = ret; - return WINED3D_OK; + return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE]; } -static void wined3d_event_query_destroy(struct wined3d_event_query *query) +void wined3d_event_query_destroy(struct wined3d_event_query *query) { if (query->context) context_free_event_query(query); HeapFree(GetProcessHeap(), 0, query); } -static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) +enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) { struct wined3d_context *context; const struct wined3d_gl_info *gl_info; @@ -72,7 +58,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_e return WINED3D_EVENT_QUERY_WRONG_THREAD; } - context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, query->context->current_rt); gl_info = context->gl_info; ENTER_GL(); @@ -125,7 +111,75 @@ static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_e return ret; } -static void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) +enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) +{ + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + enum wined3d_event_query_result ret; + + TRACE("(%p)\n", query); + + if (!query->context) + { + TRACE("Query not started\n"); + return WINED3D_EVENT_QUERY_NOT_STARTED; + } + gl_info = query->context->gl_info; + + if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC]) + { + /* A glFinish does not reliably wait for draws in other contexts. The caller has + * to find its own way to cope with the thread switch + */ + WARN("Event query finished from wrong thread\n"); + return WINED3D_EVENT_QUERY_WRONG_THREAD; + } + + context = context_acquire(device, query->context->current_rt); + + ENTER_GL(); + if (gl_info->supported[ARB_SYNC]) + { + GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, ~(GLuint64)0)); + checkGLcall("glClientWaitSync"); + + switch (gl_ret) + { + case GL_ALREADY_SIGNALED: + case GL_CONDITION_SATISFIED: + ret = WINED3D_EVENT_QUERY_OK; + break; + + /* We don't expect a timeout for a ~584 year wait */ + default: + ERR("glClientWaitSync returned %#x.\n", gl_ret); + ret = WINED3D_EVENT_QUERY_ERROR; + } + } + else if (context->gl_info->supported[APPLE_FENCE]) + { + GL_EXTCALL(glFinishFenceAPPLE(query->object.id)); + checkGLcall("glFinishFenceAPPLE"); + ret = WINED3D_EVENT_QUERY_OK; + } + else if (context->gl_info->supported[NV_FENCE]) + { + GL_EXTCALL(glFinishFenceNV(query->object.id)); + checkGLcall("glFinishFenceNV"); + ret = WINED3D_EVENT_QUERY_OK; + } + else + { + ERR("Event query created without GL support\n"); + ret = WINED3D_EVENT_QUERY_ERROR; + } + LEAVE_GL(); + + context_release(context); + return ret; +} + +void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; @@ -135,17 +189,17 @@ static void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3 if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId()) { context_free_event_query(query); - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); context_alloc_event_query(context, query); } else { - context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, query->context->current_rt); } } else { - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); context_alloc_event_query(context, query); } @@ -293,7 +347,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, return S_OK; } - context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); @@ -430,12 +484,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D FIXME("Wrong thread, can't restart query.\n"); context_free_occlusion_query(query); - context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL); context_alloc_occlusion_query(context, query); } else { - context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -446,7 +500,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D else { if (query->context) context_free_occlusion_query(query); - context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, NULL); context_alloc_occlusion_query(context, query); } @@ -470,7 +524,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D } else { - context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -525,7 +579,6 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3DQUERYTYPE type, IUnknown *parent) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - HRESULT hr; switch (type) { @@ -548,9 +601,7 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, case WINED3DQUERYTYPE_EVENT: TRACE("Event query.\n"); - query->lpVtbl = &IWineD3DEventQuery_Vtbl; - hr = wined3d_event_query_init(gl_info, (struct wined3d_event_query **) &query->extendedData); - if (hr == E_NOTIMPL) + if (!wined3d_event_query_supported(gl_info)) { /* Half-Life 2 needs this query. It does not render the main * menu correctly otherwise. Pretend to support it, faking @@ -558,9 +609,12 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, * lowering performance. */ FIXME("Event query: Unimplemented, but pretending to be supported.\n"); } - else if(FAILED(hr)) + query->lpVtbl = &IWineD3DEventQuery_Vtbl; + query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query)); + if (!query->extendedData) { - return hr; + ERR("Failed to allocate event query memory.\n"); + return E_OUTOFMEMORY; } break; diff --git a/dll/directx/wine/wined3d/resource.c b/dll/directx/wine/wined3d/resource.c index b867586096d..67622a38942 100644 --- a/dll/directx/wine/wined3d/resource.c +++ b/dll/directx/wine/wined3d/resource.c @@ -28,7 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, + IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { struct IWineD3DResourceClass *resource = &((IWineD3DResourceImpl *)iface)->resource; @@ -247,11 +247,3 @@ HRESULT resource_get_parent(IWineD3DResource *iface, IUnknown **pParent) *pParent = This->resource.parent; return WINED3D_OK; } - -void dumpResources(struct list *list) { - IWineD3DResourceImpl *resource; - - LIST_FOR_EACH_ENTRY(resource, list, IWineD3DResourceImpl, resource.resource_list_entry) { - FIXME("Leftover resource %p with type %d,%s\n", resource, IWineD3DResource_GetType((IWineD3DResource *) resource), debug_d3dresourcetype(IWineD3DResource_GetType((IWineD3DResource *) resource))); - } -} diff --git a/dll/directx/wine/wined3d/shader.c b/dll/directx/wine/wined3d/shader.c index 307cadf804c..f26122af869 100644 --- a/dll/directx/wine/wined3d/shader.c +++ b/dll/directx/wine/wined3d/shader.c @@ -721,6 +721,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1; else if (ins.handler_idx == WINED3DSIH_IFC) reg_maps->usesifc = 1; else if (ins.handler_idx == WINED3DSIH_CALL) reg_maps->usescall = 1; + else if (ins.handler_idx == WINED3DSIH_RCP) reg_maps->usesrcp = 1; limit = ins.src_count + (ins.predicate ? 1 : 0); for (i = 0; i < limit; ++i) @@ -1150,7 +1151,11 @@ void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffe if (ins.dst_count) fe->shader_read_dst_param(fe_data, &ptr, &dst_param, &dst_rel_addr); /* Predication token */ - if (ins.predicate) ins.predicate = *ptr++; + if (ins.predicate) + { + FIXME("Predicates not implemented.\n"); + ins.predicate = *ptr++; + } /* Other source tokens */ for (i = 0; i < ins.src_count; ++i) @@ -1399,7 +1404,7 @@ static void shader_cleanup(IWineD3DBaseShader *iface) static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {} static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {} -static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {} +static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size) {} static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {} static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {} static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {} @@ -1414,8 +1419,11 @@ static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct s { /* Set the shader caps to 0 for the none shader backend */ caps->VertexShaderVersion = 0; + caps->MaxVertexShaderConst = 0; caps->PixelShaderVersion = 0; caps->PixelShader1xMaxValue = 0.0f; + caps->MaxPixelShaderConst = 0; + caps->VSClipping = FALSE; } static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup) @@ -2017,6 +2025,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, } args->color_fixup[i] = texture->resource.format_desc->color_fixup; + if (texture->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW) + args->shadow |= 1 << i; + /* Flag samplers that need NP2 texcoord fixup. */ if (!texture->baseTexture.pow2Matrix_identity) { diff --git a/dll/directx/wine/wined3d/state.c b/dll/directx/wine/wined3d/state.c index 5efe069bb19..4c6d5bfe025 100644 --- a/dll/directx/wine/wined3d/state.c +++ b/dll/directx/wine/wined3d/state.c @@ -35,31 +35,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); -#define GLINFO_LOCATION (*context->gl_info) - /* GL locking for state handlers is done by the caller. */ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context); -static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) -{ - /* Used for states which are not mapped to a gl state as-is, but used somehow different, - * e.g as a parameter for drawing, or which are unimplemented in windows d3d - */ - if(STATE_IS_RENDER(state)) { - WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0); - TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]); - } else { - /* Shouldn't have an unknown type here */ - FIXME("%d no direct mapping to gl of state with unknown type\n", state); - } -} - static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { ERR("Undefined state.\n"); } +static void state_nop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state)); +} + static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE]; @@ -108,7 +97,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { /* No z test without depth stencil buffers */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->depth_stencil) { TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ @@ -242,7 +231,8 @@ static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0]; + const struct wined3d_gl_info *gl_info = context->gl_info; int srcBlend = GL_ZERO; int dstBlend = GL_ZERO; @@ -450,10 +440,7 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state, so it may need updating */ if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) - { - const struct StateEntry *StateTable = stateblock->device->StateTable; - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); - } + stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); } static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -463,6 +450,7 @@ static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]); @@ -491,9 +479,8 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0]; + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0]; + IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0]; if (surf->CKeyFlags & WINEDDSD_CKSRCBLT) { @@ -506,10 +493,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct } if (enable_ckey || context->last_was_ckey) - { - const struct StateEntry *StateTable = stateblock->device->StateTable; - StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); - } + stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); context->last_was_ckey = enable_ckey; if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] || @@ -621,12 +605,13 @@ static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; int blendEquation = GL_FUNC_ADD; int blendEquationAlpha = GL_FUNC_ADD; /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */ if (stateblock->renderState[WINED3DRS_BLENDOPALPHA] - && !context->gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) + && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE]) { WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n"); return; @@ -779,6 +764,7 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int i; /* Note the texture color applies to all textures whereas @@ -788,7 +774,7 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, str D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col); /* And now the default texture color as well */ - for (i = 0; i < context->gl_info->limits.texture_stages; ++i) + for (i = 0; i < gl_info->limits.texture_stages; ++i) { /* Note the WINED3DRS value applies to all textures, but GL has one * per texture, so apply it now ready to be used! @@ -804,6 +790,8 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, str static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass) { + const struct wined3d_gl_info *gl_info = context->gl_info; + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)"); GL_EXTCALL(glActiveStencilFaceEXT(face)); @@ -831,7 +819,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc GLint stencilPass_ccw = GL_KEEP; /* No stencil test without a stencil buffer. */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->depth_stencil) { glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); @@ -914,7 +902,8 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + const struct wined3d_gl_info *gl_info = context->gl_info; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); @@ -927,7 +916,7 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; glStencilMask(mask); checkGLcall("glStencilMask"); @@ -1402,7 +1391,9 @@ static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, st static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - union { + const struct wined3d_gl_info *gl_info = context->gl_info; + union + { DWORD d; float f; } min, max; @@ -1423,7 +1414,9 @@ static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - union { + const struct wined3d_gl_info *gl_info = context->gl_info; + union + { DWORD d; float f; } min, max; @@ -1525,30 +1518,60 @@ static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE]; + DWORD mask0 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE]; + DWORD mask1 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE1]; + DWORD mask2 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE2]; + DWORD mask3 = stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]; TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", - Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, - Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); - glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); + mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0, + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0); + glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); checkGLcall("glColorMask(...)"); - /* depends on WINED3DRS_COLORWRITEENABLE. */ - if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F || - stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F || - stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) { - ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n", - stateblock->renderState[WINED3DRS_COLORWRITEENABLE1], - stateblock->renderState[WINED3DRS_COLORWRITEENABLE2], - stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]); + if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0) + || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf))) + { + FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n", + mask0, mask1, mask2, mask3); + FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n"); } } +static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask) +{ + GL_EXTCALL(glColorMaskIndexedEXT(index, + mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, + mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE)); +} + +static void state_colorwrite0(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 0, stateblock->renderState[WINED3DRS_COLORWRITEENABLE]); +} + +static void state_colorwrite1(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 1, stateblock->renderState[WINED3DRS_COLORWRITEENABLE1]); +} + +static void state_colorwrite2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 2, stateblock->renderState[WINED3DRS_COLORWRITEENABLE2]); +} + +static void state_colorwrite3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + set_color_mask(context->gl_info, 3, stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]); +} + static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) { @@ -1706,6 +1729,12 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, str } } +static void state_zvisible(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +{ + if (stateblock->renderState[WINED3DRS_ZVISIBLE]) + FIXME("WINED3DRS_ZVISIBLE not implemented.\n"); +} + static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) { @@ -1843,13 +1872,6 @@ static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, } } -static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) -{ - if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) { - FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n"); - } -} - static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) { @@ -3083,9 +3105,8 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0]; + IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0]; if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask) { @@ -3157,6 +3178,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s { DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); DWORD mapped_stage = stateblock->device->texUnitMap[texUnit]; + const struct wined3d_gl_info *gl_info = context->gl_info; BOOL generated; int coordIdx; @@ -3168,7 +3190,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s } if (mapped_stage == WINED3D_UNMAPPED_STAGE) return; - if (mapped_stage >= context->gl_info->limits.textures) return; + if (mapped_stage >= gl_info->limits.textures) return; GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("glActiveTextureARB"); @@ -3197,21 +3219,20 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s } } -static void unloadTexCoords(const struct wined3d_context *context) +static void unloadTexCoords(const struct wined3d_gl_info *gl_info) { unsigned int texture_idx; - for (texture_idx = 0; texture_idx < context->gl_info->limits.texture_stages; ++texture_idx) + for (texture_idx = 0; texture_idx < gl_info->limits.texture_stages; ++texture_idx) { GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } -static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock, +static void loadTexCoords(const struct wined3d_gl_info *gl_info, IWineD3DStateBlockImpl *stateblock, const struct wined3d_stream_info *si, GLuint *curVBO) { - const struct wined3d_gl_info *gl_info = context->gl_info; const UINT *offset = stateblock->streamOffset; unsigned int mapped_stage = 0; unsigned int textureNo = 0; @@ -3431,8 +3452,8 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru */ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0; - unloadTexCoords(context); - loadTexCoords(context, stateblock, &stateblock->device->strided_streams, &curVBO); + unloadTexCoords(gl_info); + loadTexCoords(gl_info, stateblock, &stateblock->device->strided_streams, &curVBO); } } @@ -3603,10 +3624,8 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w * while it was enabled, so re-apply them. */ for (i = 0; i < context->gl_info->limits.texture_stages; ++i) { - if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) { - device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply - (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context); - } + if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) + stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context); } context->last_was_pshader = FALSE; } @@ -3750,27 +3769,20 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - static BOOL once = FALSE; + WINED3DVERTEXBLENDFLAGS f = stateblock->renderState[WINED3DRS_VERTEXBLEND]; + static unsigned int once; - switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) { - case WINED3DVBF_1WEIGHTS: - case WINED3DVBF_2WEIGHTS: - case WINED3DVBF_3WEIGHTS: - if(!once) { - once = TRUE; - /* TODO: Implement vertex blending in drawStridedSlow */ - FIXME("Vertex blending enabled, but not supported by hardware\n"); - } - break; + if (f == WINED3DVBF_DISABLE) return; - case WINED3DVBF_TWEENING: - WARN("Tweening not supported yet\n"); - } + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f); + else WARN("Vertex blend flags %#x not supported.\n", f); } static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND]; + const struct wined3d_gl_info *gl_info = context->gl_info; + static unsigned int once; switch(val) { case WINED3DVBF_1WEIGHTS: @@ -3787,7 +3799,7 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s if (!stateblock->device->vertexBlendUsed) { unsigned int i; - for (i = 1; i < context->gl_info->limits.blends; ++i) + for (i = 1; i < gl_info->limits.blends; ++i) { if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) { @@ -3798,19 +3810,15 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s } break; + case WINED3DVBF_TWEENING: + case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */ + if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val); + else WARN("Vertex blend flags %#x not supported.\n", val); + /* Fall through. */ case WINED3DVBF_DISABLE: - case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */ glDisable(GL_VERTEX_BLEND_ARB); checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)"); break; - - case WINED3DVBF_TWEENING: - /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have - * vertex weights in the vertices? - * For now we don't report that as supported, so a warn should suffice - */ - WARN("Tweening not supported yet\n"); - break; } } @@ -3975,10 +3983,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock /* This should match any arrays loaded in loadVertexData. * TODO: Only load / unload arrays if we have to. */ -static inline void unloadVertexData(const struct wined3d_context *context) +static inline void unloadVertexData(const struct wined3d_gl_info *gl_info) { - const struct wined3d_gl_info *gl_info = context->gl_info; - glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); @@ -3990,11 +3996,13 @@ static inline void unloadVertexData(const struct wined3d_context *context) { glDisableClientState(GL_WEIGHT_ARRAY_ARB); } - unloadTexCoords(context); + unloadTexCoords(gl_info); } -static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i) +static inline void unload_numbered_array(struct wined3d_context *context, int i) { + const struct wined3d_gl_info *gl_info = context->gl_info; + GL_EXTCALL(glDisableVertexAttribArrayARB(i)); checkGLcall("glDisableVertexAttribArrayARB(reg)"); @@ -4004,7 +4012,7 @@ static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, str /* This should match any arrays loaded in loadNumberedArrays * TODO: Only load / unload arrays if we have to. */ -static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) +static inline void unloadNumberedArrays(struct wined3d_context *context) { /* disable any attribs (this is the same for both GLSL and ARB modes) */ GLint maxAttribs = 16; @@ -4016,7 +4024,7 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, stru if (glGetError() != GL_NO_ERROR) maxAttribs = 16; for (i = 0; i < maxAttribs; ++i) { - unload_numbered_array(stateblock, context, i); + unload_numbered_array(context, i); } } @@ -4036,14 +4044,14 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, for (i = 0; i < MAX_ATTRIBS; i++) { if (!(stream_info->use_map & (1 << i))) { - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); continue; } /* Do not load instance data. It will be specified using glTexCoord by drawprim */ if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA) { - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); stateblock->device->instancedDraw = TRUE; continue; } @@ -4102,10 +4110,10 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, if (stream_info->elements[i].buffer_object) { vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; - ptr += (long) buffer_get_sysmem(vb); + ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info); } - if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); + if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i); switch (stream_info->elements[i].format_desc->format) { @@ -4225,11 +4233,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB GL_EXTCALL(glVertexBlendARB(e->format_desc->component_count + 1)); - VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n", - WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) , - sd->u.s.blendWeights.dwStride, - sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo])); - if (curVBO != e->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); @@ -4237,8 +4240,13 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB curVBO = e->buffer_object; } - GL_EXTCALL(glWeightPointerARB)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, - e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n", + e->format_desc->gl_vtx_format, + e->format_desc->gl_vtx_type, + e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glWeightPointerARB(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glWeightPointerARB"); @@ -4279,8 +4287,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB /* Vertex Pointers -----------------------------------------*/ if (si->use_map & (1 << WINED3D_FFP_POSITION)) { - VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data)); - e = &si->elements[WINED3D_FFP_POSITION]; if (curVBO != e->buffer_object) { @@ -4299,9 +4305,16 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB */ if (!e->buffer_object) { + TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glVertexPointer(3 /* min(e->format_desc->gl_vtx_format, 3) */, e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); - } else { + } + else + { + TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n", + e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glVertexPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); } @@ -4313,8 +4326,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB /* Normals -------------------------------------------------*/ if (si->use_map & (1 << WINED3D_FFP_NORMAL)) { - VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data)); - e = &si->elements[WINED3D_FFP_NORMAL]; if (curVBO != e->buffer_object) { @@ -4322,6 +4333,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB checkGLcall("glBindBufferARB"); curVBO = e->buffer_object; } + + TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glNormalPointer(e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glNormalPointer(...)"); @@ -4344,8 +4358,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB if (si->use_map & (1 << WINED3D_FFP_DIFFUSE)) { - VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); - e = &si->elements[WINED3D_FFP_DIFFUSE]; if (curVBO != e->buffer_object) { @@ -4354,6 +4366,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB curVBO = e->buffer_object; } + TRACE("glColorPointer(%#x, %#x %#x, %p);\n", + e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glColorPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); @@ -4369,7 +4384,6 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB if (si->use_map & (1 << WINED3D_FFP_SPECULAR)) { TRACE("setting specular colour\n"); - VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); e = &si->elements[WINED3D_FFP_SPECULAR]; if (gl_info->supported[EXT_SECONDARY_COLOR]) @@ -4391,8 +4405,10 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts * 4 component secondary colors use it */ - GL_EXTCALL(glSecondaryColorPointerEXT)(format, type, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glSecondaryColorPointerEXT(format, type, ...)"); } else @@ -4400,25 +4416,29 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB switch(type) { case GL_UNSIGNED_BYTE: - GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)"); break; default: FIXME("Add 4 component specular color pointers for type %x\n", type); /* Make sure that the right color component is dropped */ - GL_EXTCALL(glSecondaryColorPointerEXT)(3, type, - e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); + GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx])); checkGLcall("glSecondaryColorPointerEXT(3, type, ...)"); } } glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - } else { - - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); } } else @@ -4427,15 +4447,15 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB { GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0); checkGLcall("glSecondaryColor3fEXT(0, 0, 0)"); - } else { - - /* Missing specular color is not critical, no warnings */ - VTRACE(("Specular colour is not supported in this GL implementation\n")); + } + else + { + WARN("Specular colour is not supported in this GL implementation.\n"); } } /* Texture coords -------------------------------------------*/ - loadTexCoords(context, stateblock, si, &curVBO); + loadTexCoords(gl_info, stateblock, si, &curVBO); } static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -4446,13 +4466,13 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi if (context->numberedArraysLoaded && !load_numbered) { - unloadNumberedArrays(stateblock, context); + unloadNumberedArrays(context); context->numberedArraysLoaded = FALSE; context->numbered_array_mask = 0; } else if (context->namedArraysLoaded) { - unloadVertexData(context); + unloadVertexData(context->gl_info); context->namedArraysLoaded = FALSE; } @@ -4618,9 +4638,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s context->last_was_vshader = useVertexShaderFunction; - if(updateFog) { - device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context); - } + if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context); + if(!useVertexShaderFunction) { int i; for(i = 0; i < MAX_TEXTURES; i++) { @@ -4633,7 +4652,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0]; UINT width, height; WINED3DVIEWPORT vp = stateblock->viewport; @@ -4671,6 +4690,8 @@ static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) { state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context); } + if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) + shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context); } static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) @@ -4789,7 +4810,7 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)stateblock->device->render_targets[0]; + IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0]; RECT *pRect = &stateblock->scissorRect; UINT height; UINT width; @@ -4812,6 +4833,8 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { + const struct wined3d_gl_info *gl_info = context->gl_info; + if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) { GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); } else { @@ -4833,17 +4856,17 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi } const struct StateEntryTemplate misc_state_template[] = { - { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, - { STATE_STREAMSRC, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE }, { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE }, { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE }, @@ -4851,58 +4874,59 @@ const struct StateEntryTemplate misc_state_template[] = { * vshader loadings are untied from each other */ { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE }, - { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE }, + { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE }, { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT }, + { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE }, @@ -4916,9 +4940,9 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE }, @@ -4933,35 +4957,35 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE }, { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE }, @@ -4969,28 +4993,33 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 }, { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX }, { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 }, + { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR }, { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE }, /* Samplers */ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE }, @@ -5017,8 +5046,8 @@ const struct StateEntryTemplate misc_state_template[] = { const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_VSHADER, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE }, - { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, + { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE }, + { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE }, /* Clip planes */ { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE }, @@ -5067,14 +5096,14 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { /* Transform states follow */ { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE }, { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE }, @@ -5349,36 +5378,39 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE }, /* Fog */ { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE }, { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND }, { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE }, { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE }, + /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported, * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states. * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix @@ -5412,96 +5444,95 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE }, - { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE }, { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_BORDERCOLOR), { STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, - { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, + { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE }, { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE }, @@ -5512,13 +5543,13 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; -#undef GLINFO_LOCATION /* Context activation is done by the caller. */ static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { } static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps) { + pCaps->PrimitiveMiscCaps = 0; pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD | WINED3DTEXOPCAPS_ADDSIGNED | WINED3DTEXOPCAPS_ADDSIGNED2X | @@ -5626,20 +5657,94 @@ static void prune_invalid_states(struct StateEntry *state_table, const struct wi state_table[i].representative = 0; state_table[i].apply = state_undefined; } + + start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends)); + last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)); + for (i = start; i <= last; ++i) + { + state_table[i].representative = 0; + state_table[i].apply = state_undefined; + } } static void validate_state_table(struct StateEntry *state_table) { - unsigned int i; + static const struct + { + DWORD first; + DWORD last; + } + rs_holes[] = + { + { 1, 1}, + { 3, 3}, + { 17, 18}, + { 21, 21}, + { 42, 45}, + { 61, 127}, + {149, 150}, + {169, 169}, + {177, 177}, + {196, 197}, + { 0, 0}, + }; + static const DWORD simple_states[] = + { + STATE_MATERIAL, + STATE_VDECL, + STATE_STREAMSRC, + STATE_INDEXBUFFER, + STATE_VERTEXSHADERCONSTANT, + STATE_PIXELSHADERCONSTANT, + STATE_VSHADER, + STATE_PIXELSHADER, + STATE_VIEWPORT, + STATE_SCISSORRECT, + STATE_FRONTFACE, + }; + unsigned int i, current; + + for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i) + { + if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first)) + { + if (!state_table[i].representative) + ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i); + } + else if (state_table[i].representative) + ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i); + + if (i == STATE_RENDER(rs_holes[current].last)) ++current; + } + + for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i) + { + if (!state_table[simple_states[i]].representative) + ERR("State %s (%#x) should have a representative.\n", + debug_d3dstate(simple_states[i]), simple_states[i]); + } for (i = 0; i < STATE_HIGHEST + 1; ++i) { DWORD rep = state_table[i].representative; - if (rep && !state_table[rep].representative) + if (rep) { - ERR("State %s (%#x) has invalid representative %s (%#x).\n", - debug_d3dstate(i), i, debug_d3dstate(rep), rep); - state_table[i].representative = 0; + if (state_table[rep].representative != rep) + { + ERR("State %s (%#x) has invalid representative %s (%#x).\n", + debug_d3dstate(i), i, debug_d3dstate(rep), rep); + state_table[i].representative = 0; + } + + if (rep != i) + { + if (state_table[i].apply) + ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i); + } + else if (!state_table[i].apply) + { + ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i); + } } } } @@ -5696,7 +5801,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ * applying later lines, but do not record anything in the state * table */ - if(!cur[i].content.apply) continue; + if (!cur[i].content.representative) continue; handlers = num_handlers(multistate_funcs[cur[i].state]); multistate_funcs[cur[i].state][handlers] = cur[i].content.apply; diff --git a/dll/directx/wine/wined3d/stateblock.c b/dll/directx/wine/wined3d/stateblock.c index 48f9eacc453..1696646849e 100644 --- a/dll/directx/wine/wined3d/stateblock.c +++ b/dll/directx/wine/wined3d/stateblock.c @@ -757,7 +757,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) { TRACE("Updating scissor rect.\n"); - targetStateBlock->scissorRect = This->scissorRect; + This->scissorRect = targetStateBlock->scissorRect; } map = This->changed.streamSource; @@ -866,7 +866,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) return WINED3D_OK; } -static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl *This) +static void apply_lights(IWineD3DDevice *device, const IWineD3DStateBlockImpl *This) { UINT i; for(i = 0; i < LIGHTMAP_SIZE; i++) { @@ -876,8 +876,8 @@ static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl * { const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry); - IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms); - IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1); + IWineD3DDevice_SetLight(device, light->OriginalIndex, &light->OriginalParms); + IWineD3DDevice_SetLightEnable(device, light->OriginalIndex, light->glIndex != -1); } } } @@ -885,58 +885,58 @@ static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl * static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; - IWineD3DDevice *pDevice = (IWineD3DDevice *)This->device; + IWineD3DDevice *device = (IWineD3DDevice *)This->device; unsigned int i; DWORD map; - TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice); + TRACE("(%p) : Applying state block %p ------------------v\n", This, device); TRACE("Blocktype: %d\n", This->blockType); - if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader); + if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(device, This->vertexShader); /* Vertex Shader Constants */ for (i = 0; i < This->num_contained_vs_consts_f; ++i) { - IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i], + IWineD3DDevice_SetVertexShaderConstantF(device, This->contained_vs_consts_f[i], This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1); } for (i = 0; i < This->num_contained_vs_consts_i; ++i) { - IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i], + IWineD3DDevice_SetVertexShaderConstantI(device, This->contained_vs_consts_i[i], This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1); } for (i = 0; i < This->num_contained_vs_consts_b; ++i) { - IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i], + IWineD3DDevice_SetVertexShaderConstantB(device, This->contained_vs_consts_b[i], This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1); } - apply_lights(pDevice, This); + apply_lights(device, This); - if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader); + if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(device, This->pixelShader); /* Pixel Shader Constants */ for (i = 0; i < This->num_contained_ps_consts_f; ++i) { - IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i], + IWineD3DDevice_SetPixelShaderConstantF(device, This->contained_ps_consts_f[i], This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1); } for (i = 0; i < This->num_contained_ps_consts_i; ++i) { - IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i], + IWineD3DDevice_SetPixelShaderConstantI(device, This->contained_ps_consts_i[i], This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1); } for (i = 0; i < This->num_contained_ps_consts_b; ++i) { - IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i], + IWineD3DDevice_SetPixelShaderConstantB(device, This->contained_ps_consts_b[i], This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1); } /* Render */ for (i = 0; i < This->num_contained_render_states; ++i) { - IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i], + IWineD3DDevice_SetRenderState(device, This->contained_render_states[i], This->renderState[This->contained_render_states[i]]); } @@ -946,7 +946,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) DWORD stage = This->contained_tss_states[i].stage; DWORD state = This->contained_tss_states[i].state; - IWineD3DDevice_SetTextureStageState(pDevice, stage, state, This->textureState[stage][state]); + IWineD3DDevice_SetTextureStageState(device, stage, state, This->textureState[stage][state]); } /* Sampler states */ @@ -957,12 +957,12 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) DWORD value = This->samplerState[stage][state]; if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS; - IWineD3DDevice_SetSamplerState(pDevice, stage, state, value); + IWineD3DDevice_SetSamplerState(device, stage, state, value); } for (i = 0; i < This->num_contained_transform_states; ++i) { - IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i], + IWineD3DDevice_SetTransform(device, This->contained_transform_states[i], &This->transforms[This->contained_transform_states[i]]); } @@ -974,40 +974,40 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) if (This->changed.indices) { - IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt); - IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); + IWineD3DDevice_SetIndexBuffer(device, This->pIndexData, This->IndexFmt); + IWineD3DDevice_SetBaseVertexIndex(device, This->baseVertexIndex); } if (This->changed.vertexDecl && This->vertexDecl) { - IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl); + IWineD3DDevice_SetVertexDeclaration(device, This->vertexDecl); } if (This->changed.material) { - IWineD3DDevice_SetMaterial(pDevice, &This->material); + IWineD3DDevice_SetMaterial(device, &This->material); } if (This->changed.viewport) { - IWineD3DDevice_SetViewport(pDevice, &This->viewport); + IWineD3DDevice_SetViewport(device, &This->viewport); } if (This->changed.scissorRect) { - IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect); + IWineD3DDevice_SetScissorRect(device, &This->scissorRect); } map = This->changed.streamSource; for (i = 0; map; map >>= 1, ++i) { - if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]); + if (map & 1) IWineD3DDevice_SetStreamSource(device, i, This->streamSource[i], 0, This->streamStride[i]); } map = This->changed.streamFreq; for (i = 0; map; map >>= 1, ++i) { - if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]); + if (map & 1) IWineD3DDevice_SetStreamSourceFreq(device, i, This->streamFreq[i] | This->streamFlags[i]); } map = This->changed.textures; @@ -1018,7 +1018,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) if (!(map & 1)) continue; stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS; - IWineD3DDevice_SetTexture(pDevice, stage, This->textures[i]); + IWineD3DDevice_SetTexture(device, stage, This->textures[i]); } map = This->changed.clipplane; @@ -1032,7 +1032,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) clip[1] = This->clipplane[i][1]; clip[2] = This->clipplane[i][2]; clip[3] = This->clipplane[i][3]; - IWineD3DDevice_SetClipPlane(pDevice, i, clip); + IWineD3DDevice_SetClipPlane(device, i, clip); } This->device->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1; @@ -1044,7 +1044,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) break; } } - TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice); + TRACE("(%p) : Applied state block %p ------------------^\n", This, device); return WINED3D_OK; } @@ -1052,8 +1052,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) { IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; IWineD3DDevice *device = (IWineD3DDevice *)This->device; - IWineD3DDeviceImpl *ThisDevice = (IWineD3DDeviceImpl *)device; - const struct wined3d_gl_info *gl_info = &ThisDevice->adapter->gl_info; + IWineD3DDeviceImpl *device_impl = (IWineD3DDeviceImpl *)device; + const struct wined3d_gl_info *gl_info = &device_impl->adapter->gl_info; union { WINED3DLINEPATTERN lp; DWORD d; @@ -1070,7 +1070,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat /* Note this may have a large overhead but it should only be executed once, in order to initialize the complete state of the device and all opengl equivalents */ - TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, ThisDevice); + TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, device); /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */ This->blockType = WINED3DSBT_INIT; @@ -1083,11 +1083,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat TRACE("Render states\n"); /* Render states: */ - if (ThisDevice->auto_depth_stencil_buffer != NULL) { + if (device_impl->auto_depth_stencil) IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_TRUE); - } else { + else IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_FALSE); - } IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE, WINED3DFILL_SOLID); IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE, WINED3DSHADE_GOURAUD); lp.lp.wRepeatFactor = 0; diff --git a/dll/directx/wine/wined3d/surface.c b/dll/directx/wine/wined3d/surface.c index d17d35cc16d..0903f6eecaf 100644 --- a/dll/directx/wine/wined3d/surface.c +++ b/dll/directx/wine/wined3d/surface.c @@ -34,8 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); WINE_DECLARE_DEBUG_CHANNEL(d3d); -#define GLINFO_LOCATION (*gl_info) - static void surface_cleanup(IWineD3DSurfaceImpl *This) { IWineD3DDeviceImpl *device = This->resource.device; @@ -51,7 +49,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This) * target, Uninit3D() will activate a context before doing anything. */ if (device->render_targets && device->render_targets[0]) { - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } ENTER_GL(); @@ -98,7 +96,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This) if (context) context_release(context); } -UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT alignment, UINT width, UINT height) +UINT surface_calculate_size(const struct wined3d_format_desc *format_desc, UINT alignment, UINT width, UINT height) { UINT size; @@ -123,13 +121,233 @@ UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT al return size; } +struct blt_info +{ + GLenum binding; + GLenum bind_target; + enum tex_types tex_type; + GLfloat coords[4][3]; +}; + +struct float_rect +{ + float l; + float t; + float r; + float b; +}; + +static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f) +{ + f->l = ((r->left * 2.0f) / w) - 1.0f; + f->t = ((r->top * 2.0f) / h) - 1.0f; + f->r = ((r->right * 2.0f) / w) - 1.0f; + f->b = ((r->bottom * 2.0f) / h) - 1.0f; +} + +static void surface_get_blt_info(GLenum target, const RECT *rect_in, GLsizei w, GLsizei h, struct blt_info *info) +{ + GLfloat (*coords)[3] = info->coords; + RECT rect; + struct float_rect f; + + if (rect_in) + rect = *rect_in; + else + { + rect.left = 0; + rect.top = h; + rect.right = w; + rect.bottom = 0; + } + + switch (target) + { + default: + FIXME("Unsupported texture target %#x\n", target); + /* Fall back to GL_TEXTURE_2D */ + case GL_TEXTURE_2D: + info->binding = GL_TEXTURE_BINDING_2D; + info->bind_target = GL_TEXTURE_2D; + info->tex_type = tex_2d; + coords[0][0] = (float)rect.left / w; + coords[0][1] = (float)rect.top / h; + coords[0][2] = 0.0f; + + coords[1][0] = (float)rect.right / w; + coords[1][1] = (float)rect.top / h; + coords[1][2] = 0.0f; + + coords[2][0] = (float)rect.left / w; + coords[2][1] = (float)rect.bottom / h; + coords[2][2] = 0.0f; + + coords[3][0] = (float)rect.right / w; + coords[3][1] = (float)rect.bottom / h; + coords[3][2] = 0.0f; + break; + + case GL_TEXTURE_RECTANGLE_ARB: + info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; + info->bind_target = GL_TEXTURE_RECTANGLE_ARB; + info->tex_type = tex_rect; + coords[0][0] = rect.left; coords[0][1] = rect.top; coords[0][2] = 0.0f; + coords[1][0] = rect.right; coords[1][1] = rect.top; coords[1][2] = 0.0f; + coords[2][0] = rect.left; coords[2][1] = rect.bottom; coords[2][2] = 0.0f; + coords[3][0] = rect.right; coords[3][1] = rect.bottom; coords[3][2] = 0.0f; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = 1.0f; coords[0][1] = -f.t; coords[0][2] = -f.l; + coords[1][0] = 1.0f; coords[1][1] = -f.t; coords[1][2] = -f.r; + coords[2][0] = 1.0f; coords[2][1] = -f.b; coords[2][2] = -f.l; + coords[3][0] = 1.0f; coords[3][1] = -f.b; coords[3][2] = -f.r; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = -1.0f; coords[0][1] = -f.t; coords[0][2] = f.l; + coords[1][0] = -1.0f; coords[1][1] = -f.t; coords[1][2] = f.r; + coords[2][0] = -1.0f; coords[2][1] = -f.b; coords[2][2] = f.l; + coords[3][0] = -1.0f; coords[3][1] = -f.b; coords[3][2] = f.r; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = f.l; coords[0][1] = 1.0f; coords[0][2] = f.t; + coords[1][0] = f.r; coords[1][1] = 1.0f; coords[1][2] = f.t; + coords[2][0] = f.l; coords[2][1] = 1.0f; coords[2][2] = f.b; + coords[3][0] = f.r; coords[3][1] = 1.0f; coords[3][2] = f.b; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = f.l; coords[0][1] = -1.0f; coords[0][2] = -f.t; + coords[1][0] = f.r; coords[1][1] = -1.0f; coords[1][2] = -f.t; + coords[2][0] = f.l; coords[2][1] = -1.0f; coords[2][2] = -f.b; + coords[3][0] = f.r; coords[3][1] = -1.0f; coords[3][2] = -f.b; + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = f.l; coords[0][1] = -f.t; coords[0][2] = 1.0f; + coords[1][0] = f.r; coords[1][1] = -f.t; coords[1][2] = 1.0f; + coords[2][0] = f.l; coords[2][1] = -f.b; coords[2][2] = 1.0f; + coords[3][0] = f.r; coords[3][1] = -f.b; coords[3][2] = 1.0f; + break; + + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; + info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; + info->tex_type = tex_cube; + cube_coords_float(&rect, w, h, &f); + + coords[0][0] = -f.l; coords[0][1] = -f.t; coords[0][2] = -1.0f; + coords[1][0] = -f.r; coords[1][1] = -f.t; coords[1][2] = -1.0f; + coords[2][0] = -f.l; coords[2][1] = -f.b; coords[2][2] = -1.0f; + coords[3][0] = -f.r; coords[3][1] = -f.b; coords[3][2] = -1.0f; + break; + } +} + +static inline void surface_get_rect(IWineD3DSurfaceImpl *This, const RECT *rect_in, RECT *rect_out) +{ + if (rect_in) + *rect_out = *rect_in; + else + { + rect_out->left = 0; + rect_out->top = 0; + rect_out->right = This->currentDesc.Width; + rect_out->bottom = This->currentDesc.Height; + } +} + +/* GL locking and context activation is done by the caller */ +void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) +{ + IWineD3DBaseTextureImpl *texture; + struct blt_info info; + + surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info); + + glEnable(info.bind_target); + checkGLcall("glEnable(bind_target)"); + + /* Bind the texture */ + glBindTexture(info.bind_target, src_surface->texture_name); + checkGLcall("glBindTexture"); + + /* Filtering for StretchRect */ + glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER, + wined3d_gl_mag_filter(magLookup, Filter)); + checkGLcall("glTexParameteri"); + glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER, + wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE)); + checkGLcall("glTexParameteri"); + glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + checkGLcall("glTexEnvi"); + + /* Draw a quad */ + glBegin(GL_TRIANGLE_STRIP); + glTexCoord3fv(info.coords[0]); + glVertex2i(dst_rect->left, dst_rect->top); + + glTexCoord3fv(info.coords[1]); + glVertex2i(dst_rect->right, dst_rect->top); + + glTexCoord3fv(info.coords[2]); + glVertex2i(dst_rect->left, dst_rect->bottom); + + glTexCoord3fv(info.coords[3]); + glVertex2i(dst_rect->right, dst_rect->bottom); + glEnd(); + + /* Unbind the texture */ + glBindTexture(info.bind_target, 0); + checkGLcall("glBindTexture(info->bind_target, 0)"); + + /* We changed the filtering settings on the texture. Inform the + * container about this to get the filters reset properly next draw. */ + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DBaseTexture, (void **)&texture))) + { + texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; + texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; + texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; + IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture); + } +} + HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment, UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type, UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); void (*cleanup)(IWineD3DSurfaceImpl *This); unsigned int resource_size; HRESULT hr; @@ -226,7 +444,7 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, } /* Mark the texture as dirty so that it gets loaded first time around. */ - surface_add_dirty_rect((IWineD3DSurface *)surface, NULL); + surface_add_dirty_rect(surface, NULL); list_init(&surface->renderbuffers); TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size); @@ -243,64 +461,59 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, return hr; } -static void surface_force_reload(IWineD3DSurface *iface) +static void surface_force_reload(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - - This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); + surface->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); } -void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb) +void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint new_name, BOOL srgb) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; GLuint *name; DWORD flag; + TRACE("surface %p, new_name %u, srgb %#x.\n", surface, new_name, srgb); + if(srgb) { - name = &This->texture_name_srgb; + name = &surface->texture_name_srgb; flag = SFLAG_INSRGBTEX; } else { - name = &This->texture_name; + name = &surface->texture_name; flag = SFLAG_INTEXTURE; } - TRACE("(%p) : setting texture name %u\n", This, new_name); - if (!*name && new_name) { /* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the * surface has no texture name yet. See if we can get rid of this. */ - if (This->Flags & flag) + if (surface->Flags & flag) ERR("Surface has SFLAG_INTEXTURE set, but no texture name\n"); - IWineD3DSurface_ModifyLocation(iface, flag, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, flag, FALSE); } *name = new_name; - surface_force_reload(iface); + surface_force_reload(surface); } -void surface_set_texture_target(IWineD3DSurface *iface, GLenum target) +void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + TRACE("surface %p, target %#x.\n", surface, target); - TRACE("(%p) : setting target %#x\n", This, target); - - if (This->texture_target != target) + if (surface->texture_target != target) { if (target == GL_TEXTURE_RECTANGLE_ARB) { - This->Flags &= ~SFLAG_NORMCOORD; + surface->Flags &= ~SFLAG_NORMCOORD; } - else if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) + else if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB) { - This->Flags |= SFLAG_NORMCOORD; + surface->Flags |= SFLAG_NORMCOORD; } } - This->texture_target = target; - surface_force_reload(iface); + surface->texture_target = target; + surface_force_reload(surface); } /* Context activation is done by the caller. */ @@ -334,8 +547,9 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) { /* This function checks if the primary render target uses the 8bit paletted format. */ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device) { - if (device->render_targets && device->render_targets[0]) { - IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0]; + if (device->render_targets && device->render_targets[0]) + { + IWineD3DSurfaceImpl *render_target = device->render_targets[0]; if ((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET) && (render_target->resource.format_desc->format == WINED3DFMT_P8_UINT)) return TRUE; @@ -343,15 +557,12 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device) return FALSE; } -#undef GLINFO_LOCATION - -#define GLINFO_LOCATION This->resource.device->adapter->gl_info - /* This call just downloads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_download_data(IWineD3DSurfaceImpl *This) { - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; +static void surface_download_data(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info) +{ + const struct wined3d_format_desc *format_desc = This->resource.format_desc; /* Only support read back of converted P8 surfaces */ if (This->Flags & SFLAG_CONVERTED && format_desc->format != WINED3DFMT_P8_UINT) @@ -502,11 +713,28 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { /* This call just uploads data, the caller is responsible for binding the * correct texture. */ /* Context activation is done by the caller. */ -static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; +static void surface_upload_data(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info, + const struct wined3d_format_desc *format_desc, BOOL srgb, const GLvoid *data) +{ + GLsizei width = This->currentDesc.Width; + GLsizei height = This->currentDesc.Height; + GLenum internal; + + if (srgb) + { + internal = format_desc->glGammaInternal; + } + else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(This)) + { + internal = format_desc->rtInternal; + } + else + { + internal = format_desc->glInternal; + } TRACE("This %p, internal %#x, width %d, height %d, format %#x, type %#x, data %p.\n", - This, internal, width, height, format, type, data); + This, internal, width, height, format_desc->glFormat, format_desc->glType, data); TRACE("target %#x, level %u, resource size %u.\n", This->texture_target, This->texture_level, This->resource.size); @@ -536,7 +764,7 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi TRACE("Calling glTexSubImage2D.\n"); glTexSubImage2D(This->texture_target, This->texture_level, - 0, 0, width, height, format, type, data); + 0, 0, width, height, format_desc->glFormat, format_desc->glType, data); checkGLcall("glTexSubImage2D"); } @@ -547,32 +775,58 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi } LEAVE_GL(); + + if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) + { + IWineD3DDeviceImpl *device = This->resource.device; + unsigned int i; + + for (i = 0; i < device->numContexts; ++i) + { + context_surface_update(device->contexts[i], This); + } + } } /* This call just allocates the texture, the caller is responsible for binding * the correct texture. */ /* Context activation is done by the caller. */ -static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) { - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; +static void surface_allocate_surface(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info, + const struct wined3d_format_desc *format_desc, BOOL srgb) +{ BOOL enable_client_storage = FALSE; + GLsizei width = This->pow2Width; + GLsizei height = This->pow2Height; const BYTE *mem = NULL; + GLenum internal; + + if (srgb) + { + internal = format_desc->glGammaInternal; + } + else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(This)) + { + internal = format_desc->rtInternal; + } + else + { + internal = format_desc->glInternal; + } if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale; TRACE("(%p) : Creating surface (target %#x) level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n", This, This->texture_target, This->texture_level, debug_d3dformat(format_desc->format), - internal, width, height, format, type); + internal, width, height, format_desc->glFormat, format_desc->glType); ENTER_GL(); if (gl_info->supported[APPLE_CLIENT_STORAGE]) { - if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_OVERSIZE | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) { + if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) { /* In some cases we want to disable client storage. * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... - * SFLAG_OVERSIZE: The gl texture is smaller than the allocated memory * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface * allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively */ @@ -598,7 +852,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, else { glTexImage2D(This->texture_target, This->texture_level, - internal, width, height, 0, format, type, mem); + internal, width, height, 0, format_desc->glFormat, format_desc->glType, mem); checkGLcall("glTexImage2D"); } @@ -613,15 +867,15 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, * render target dimensions. With FBOs, the dimensions have to be an exact match. */ /* TODO: We should synchronize the renderbuffer's content with the texture's content. */ /* GL locking is done by the caller */ -void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; +void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height) +{ + const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; renderbuffer_entry_t *entry; GLuint renderbuffer = 0; unsigned int src_width, src_height; - src_width = This->pow2Width; - src_height = This->pow2Height; + src_width = surface->pow2Width; + src_height = surface->pow2Height; /* A depth stencil smaller than the render target is not valid */ if (width > src_width || height > src_height) return; @@ -630,51 +884,53 @@ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int wi if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || (width == src_width && height == src_height)) { - This->current_renderbuffer = NULL; + surface->current_renderbuffer = NULL; return; } /* Look if we've already got a renderbuffer of the correct dimensions */ - LIST_FOR_EACH_ENTRY(entry, &This->renderbuffers, renderbuffer_entry_t, entry) { - if (entry->width == width && entry->height == height) { + LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, renderbuffer_entry_t, entry) + { + if (entry->width == width && entry->height == height) + { renderbuffer = entry->id; - This->current_renderbuffer = entry; + surface->current_renderbuffer = entry; break; } } - if (!renderbuffer) { + if (!renderbuffer) + { gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer); gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, - This->resource.format_desc->glInternal, width, height); + surface->resource.format_desc->glInternal, width, height); entry = HeapAlloc(GetProcessHeap(), 0, sizeof(renderbuffer_entry_t)); entry->width = width; entry->height = height; entry->id = renderbuffer; - list_add_head(&This->renderbuffers, &entry->entry); + list_add_head(&surface->renderbuffers, &entry->entry); - This->current_renderbuffer = entry; + surface->current_renderbuffer = entry; } checkGLcall("set_compatible_renderbuffer"); } -GLenum surface_get_gl_buffer(IWineD3DSurface *iface) +GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->container; + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container; - TRACE("iface %p.\n", iface); + TRACE("surface %p.\n", surface); - if (!(This->Flags & SFLAG_SWAPCHAIN)) + if (!(surface->Flags & SFLAG_SWAPCHAIN)) { - ERR("Surface %p is not on a swapchain.\n", iface); + ERR("Surface %p is not on a swapchain.\n", surface); return GL_NONE; } - if (swapchain->backBuffer && swapchain->backBuffer[0] == iface) + if (swapchain->back_buffers && swapchain->back_buffers[0] == surface) { if (swapchain->render_to_fbo) { @@ -684,7 +940,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface) TRACE("Returning GL_BACK\n"); return GL_BACK; } - else if (swapchain->frontBuffer == iface) + else if (surface == swapchain->front_buffer) { TRACE("Returning GL_FRONT\n"); return GL_FRONT; @@ -695,35 +951,35 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface) } /* Slightly inefficient way to handle multiple dirty rects but it works :) */ -void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) +void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DBaseTexture *baseTexture = NULL; - if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE)) - IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */); + TRACE("surface %p, dirty_rect %s.\n", surface, wine_dbgstr_rect(dirty_rect)); - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); + if (!(surface->Flags & SFLAG_INSYSMEM) && (surface->Flags & SFLAG_INTEXTURE)) + /* No partial locking for textures yet. */ + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, TRUE); if (dirty_rect) { - This->dirtyRect.left = min(This->dirtyRect.left, dirty_rect->left); - This->dirtyRect.top = min(This->dirtyRect.top, dirty_rect->top); - This->dirtyRect.right = max(This->dirtyRect.right, dirty_rect->right); - This->dirtyRect.bottom = max(This->dirtyRect.bottom, dirty_rect->bottom); + surface->dirtyRect.left = min(surface->dirtyRect.left, dirty_rect->left); + surface->dirtyRect.top = min(surface->dirtyRect.top, dirty_rect->top); + surface->dirtyRect.right = max(surface->dirtyRect.right, dirty_rect->right); + surface->dirtyRect.bottom = max(surface->dirtyRect.bottom, dirty_rect->bottom); } else { - This->dirtyRect.left = 0; - This->dirtyRect.top = 0; - This->dirtyRect.right = This->currentDesc.Width; - This->dirtyRect.bottom = This->currentDesc.Height; + surface->dirtyRect.left = 0; + surface->dirtyRect.top = 0; + surface->dirtyRect.right = surface->currentDesc.Width; + surface->dirtyRect.bottom = surface->currentDesc.Height; } - TRACE("(%p) : Dirty: yes, Rect:(%d, %d, %d, %d)\n", This, This->dirtyRect.left, - This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom); - /* if the container is a basetexture then mark it dirty. */ - if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture))) + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&baseTexture))) { TRACE("Passing to container\n"); IWineD3DBaseTexture_SetDirty(baseTexture, TRUE); @@ -731,15 +987,59 @@ void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) } } -static inline BOOL surface_can_stretch_rect(IWineD3DSurfaceImpl *src, IWineD3DSurfaceImpl *dst) +static BOOL surface_convert_color_to_argb(IWineD3DSurfaceImpl *This, DWORD color, DWORD *argb_color) { - return ((src->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (src->resource.usage & WINED3DUSAGE_RENDERTARGET)) - && ((dst->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) - || (dst->resource.usage & WINED3DUSAGE_RENDERTARGET)) - && (src->resource.format_desc->format == dst->resource.format_desc->format - || (is_identity_fixup(src->resource.format_desc->color_fixup) - && is_identity_fixup(dst->resource.format_desc->color_fixup))); + IWineD3DDeviceImpl *device = This->resource.device; + + switch(This->resource.format_desc->format) + { + case WINED3DFMT_P8_UINT: + { + DWORD alpha; + + if (primary_render_target_is_p8(device)) + alpha = color << 24; + else + alpha = 0xFF000000; + + if (This->palette) { + *argb_color = (alpha | + (This->palette->palents[color].peRed << 16) | + (This->palette->palents[color].peGreen << 8) | + (This->palette->palents[color].peBlue)); + } else { + *argb_color = alpha; + } + } + break; + + case WINED3DFMT_B5G6R5_UNORM: + { + if (color == 0xFFFF) { + *argb_color = 0xFFFFFFFF; + } else { + *argb_color = ((0xFF000000) | + ((color & 0xF800) << 8) | + ((color & 0x07E0) << 5) | + ((color & 0x001F) << 3)); + } + } + break; + + case WINED3DFMT_B8G8R8_UNORM: + case WINED3DFMT_B8G8R8X8_UNORM: + *argb_color = 0xFF000000 | color; + break; + + case WINED3DFMT_B8G8R8A8_UNORM: + *argb_color = color; + break; + + default: + ERR("Unhandled conversion from %s to ARGB!\n", debug_d3dformat(This->resource.format_desc->format)); + return FALSE; + } + return TRUE; } static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) @@ -764,46 +1064,49 @@ static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) IWineD3DSurface IWineD3DResource parts follow **************************************************** */ -void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) +void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb) { /* TODO: check for locks */ - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.device; + IWineD3DDeviceImpl *device = surface->resource.device; IWineD3DBaseTexture *baseTexture = NULL; - TRACE("(%p)Checking to see if the container is a base texture\n", This); - if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { - IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture; + TRACE("(%p)Checking to see if the container is a base texture\n", surface); + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&baseTexture))) + { + IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *)baseTexture; TRACE("Passing to container\n"); tex_impl->baseTexture.internal_preload(baseTexture, srgb); IWineD3DBaseTexture_Release(baseTexture); } else { struct wined3d_context *context = NULL; - TRACE("(%p) : About to load surface\n", This); + TRACE("(%p) : About to load surface\n", surface); - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT - || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) + if (surface->resource.format_desc->format == WINED3DFMT_P8_UINT + || surface->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - if(palette9_changed(This)) { + if (palette9_changed(surface)) + { TRACE("Reloading surface because the d3d8/9 palette was changed\n"); /* TODO: This is not necessarily needed with hw palettized texture support */ - IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */ - IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); } } - IWineD3DSurface_LoadTexture(iface, srgb == SRGB_SRGB ? TRUE : FALSE); + IWineD3DSurface_LoadTexture((IWineD3DSurface *)surface, srgb == SRGB_SRGB ? TRUE : FALSE); - if (This->resource.pool == WINED3DPOOL_DEFAULT) { + if (surface->resource.pool == WINED3DPOOL_DEFAULT) + { /* Tell opengl to try and keep this texture in video ram (well mostly) */ GLclampf tmp; tmp = 0.9f; ENTER_GL(); - glPrioritizeTextures(1, &This->texture_name, &tmp); + glPrioritizeTextures(1, &surface->texture_name, &tmp); LEAVE_GL(); } @@ -811,12 +1114,14 @@ void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) } } -static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) { - surface_internal_preload(iface, SRGB_ANY); +static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) +{ + surface_internal_preload((IWineD3DSurfaceImpl *)iface, SRGB_ANY); } /* Context activation is done by the caller. */ -static void surface_remove_pbo(IWineD3DSurfaceImpl *This) { +static void surface_remove_pbo(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info) +{ This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT); This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); @@ -834,27 +1139,26 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *This) { This->Flags &= ~SFLAG_PBO; } -BOOL surface_init_sysmem(IWineD3DSurface *iface) +BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - - if(!This->resource.allocatedMemory) + if (!surface->resource.allocatedMemory) { - This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT); - if(!This->resource.heapMemory) + surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + surface->resource.size + RESOURCE_ALIGNMENT); + if (!surface->resource.heapMemory) { ERR("Out of memory\n"); return FALSE; } - This->resource.allocatedMemory = - (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); + surface->resource.allocatedMemory = + (BYTE *)(((ULONG_PTR)surface->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); } else { - memset(This->resource.allocatedMemory, 0, This->resource.size); + memset(surface->resource.allocatedMemory, 0, surface->resource.size); } - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, TRUE); return TRUE; } @@ -879,8 +1183,10 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { * or the depth stencil into an FBO the texture or render buffer will be removed * and all flags get lost */ - surface_init_sysmem(iface); - } else { + surface_init_sysmem(This); + } + else + { /* Load the surface into system memory */ IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE); @@ -889,13 +1195,12 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE); This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); gl_info = context->gl_info; /* Destroy PBOs, but load them into real sysmem before */ - if(This->Flags & SFLAG_PBO) { - surface_remove_pbo(This); - } + if (This->Flags & SFLAG_PBO) + surface_remove_pbo(This, gl_info); /* Destroy fbo render buffers. This is needed for implicit render targets, for * all application-created targets the application has to release the surface @@ -936,7 +1241,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { /* Read the framebuffer back into the surface */ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, void *dest, UINT pitch) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; BYTE *mem; GLint fmt; @@ -964,26 +1270,29 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v * should help here. Furthermore unlockrect will need the context set up for blitting. The context manager will find * context->last_was_blit set on the unlock. */ - context = context_acquire(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT); + context = context_acquire(device, This); + context_apply_blit_state(context, device); + gl_info = context->gl_info; + ENTER_GL(); /* Select the correct read buffer, and give some debug output. * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (surface_is_offscreen((IWineD3DSurface *) This)) + if (surface_is_offscreen(This)) { /* Locking the primary render target which is not on a swapchain(=offscreen render target). * Read from the back buffer */ TRACE("Locking offscreen render target\n"); - glReadBuffer(myDevice->offscreenBuffer); + glReadBuffer(device->offscreenBuffer); srcIsUpsideDown = TRUE; } else { /* Onscreen surfaces are always part of a swapchain */ - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This); + GLenum buffer = surface_get_gl_buffer(This); TRACE("Locking %#x buffer\n", buffer); glReadBuffer(buffer); checkGLcall("glReadBuffer"); @@ -1005,7 +1314,8 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v { case WINED3DFMT_P8_UINT: { - if(primary_render_target_is_p8(myDevice)) { + if (primary_render_target_is_p8(device)) + { /* In case of P8 render targets the index is stored in the alpha component */ fmt = GL_ALPHA; type = GL_UNSIGNED_BYTE; @@ -1140,7 +1450,7 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v * the same color but we have no choice. * In case of P8 render targets, the index is stored in the alpha component so no conversion is needed. */ - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(myDevice)) + if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(device)) { const PALETTEENTRY *pal = NULL; DWORD width = pitch / 3; @@ -1180,20 +1490,18 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, const RECT *rect, v static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) { IWineD3DDeviceImpl *device = This->resource.device; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - int bpp; - GLenum format, internal, type; - CONVERT_TYPES convert; GLint prevRead; - BOOL alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED; - - d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb); /* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer * locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any * states in the stateblock, and no driver was found yet that had bugs in that regard. */ - context = context_acquire(device, (IWineD3DSurface *) This, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, This); + gl_info = context->gl_info; + + surface_prepare_texture(This, gl_info, srgb); surface_bind_and_dirtify(This, srgb); ENTER_GL(); @@ -1204,9 +1512,9 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (!surface_is_offscreen((IWineD3DSurface *)This)) + if (!surface_is_offscreen(This)) { - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This); + GLenum buffer = surface_get_gl_buffer(This); TRACE("Locking %#x buffer\n", buffer); ENTER_GL(); @@ -1226,12 +1534,6 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) LEAVE_GL(); } - if(!(This->Flags & alloc_flag)) { - surface_allocate_surface(This, internal, This->pow2Width, - This->pow2Height, format, type); - This->Flags |= alloc_flag; - } - ENTER_GL(); /* If !SrcIsUpsideDown we should flip the surface. * This can be done using glCopyTexSubImage2D but this @@ -1254,34 +1556,47 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb) } /* Context activation is done by the caller. */ -void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) +static void surface_prepare_texture_internal(IWineD3DSurfaceImpl *surface, + const struct wined3d_gl_info *gl_info, BOOL srgb) { DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED; - GLenum format, internal, type; - GLsizei width, height; CONVERT_TYPES convert; - int bpp; + struct wined3d_format_desc desc; if (surface->Flags & alloc_flag) return; - d3dfmt_get_conv(surface, TRUE, TRUE, &format, &internal, &type, &convert, &bpp, srgb); - if(convert != NO_CONVERSION) surface->Flags |= SFLAG_CONVERTED; + d3dfmt_get_conv(surface, TRUE, TRUE, &desc, &convert); + if(convert != NO_CONVERSION || desc.convert) surface->Flags |= SFLAG_CONVERTED; else surface->Flags &= ~SFLAG_CONVERTED; - if ((surface->Flags & SFLAG_NONPOW2) && !(surface->Flags & SFLAG_OVERSIZE)) + surface_bind_and_dirtify(surface, srgb); + surface_allocate_surface(surface, gl_info, &desc, srgb); + surface->Flags |= alloc_flag; +} + +/* Context activation is done by the caller. */ +void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info, BOOL srgb) +{ + IWineD3DBaseTextureImpl *texture; + + if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface, + &IID_IWineD3DBaseTexture, (void **)&texture))) { - width = surface->pow2Width; - height = surface->pow2Height; - } - else - { - width = surface->glRect.right - surface->glRect.left; - height = surface->glRect.bottom - surface->glRect.top; + UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count; + UINT i; + + TRACE("surface %p is a subresource of texture %p.\n", surface, texture); + + for (i = 0; i < sub_count; ++i) + { + IWineD3DSurfaceImpl *s = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i]; + surface_prepare_texture_internal(s, gl_info, srgb); + } + + IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture); } - surface_bind_and_dirtify(surface, srgb); - surface_allocate_surface(surface, internal, width, height, format, type); - surface->Flags |= alloc_flag; + surface_prepare_texture_internal(surface, gl_info, srgb); } static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) @@ -1312,7 +1627,7 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) GLenum error; struct wined3d_context *context; - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); ENTER_GL(); GL_EXTCALL(glGenBuffersARB(1, &This->pbo)); @@ -1360,10 +1675,11 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; const RECT *pass_rect = pRect; - TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory); + TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n", + iface, pLockedRect, wine_dbgstr_rect(pRect), Flags); /* This is also done in the base class, but we have to verify this before loading any data from * gl into the sysmem copy. The PBO may be mapped, a different rectangle locked, the discard flag @@ -1404,7 +1720,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED } if (!(wined3d_settings.rendertargetlock_mode == RTL_DISABLE - && ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0]))) + && ((This->Flags & SFLAG_SWAPCHAIN) || This == device->render_targets[0]))) { IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect); } @@ -1412,9 +1728,12 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED lock_end: if (This->Flags & SFLAG_PBO) { + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; - context = context_acquire(myDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); + gl_info = context->gl_info; + ENTER_GL(); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo)); checkGLcall("glBindBufferARB"); @@ -1443,7 +1762,7 @@ lock_end: * Dirtify on lock * as seen in msdn docs */ - surface_add_dirty_rect(iface, pRect); + surface_add_dirty_rect(This, pRect); /** Dirtify Container if needed */ if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) { @@ -1463,16 +1782,20 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm GLint prev_rasterpos[4]; GLint skipBytes = 0; UINT pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This); /* target is argb, 4 byte */ - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; /* Activate the correct context for the render target */ - context = context_acquire(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT); + context = context_acquire(device, This); + context_apply_blit_state(context, device); + gl_info = context->gl_info; + ENTER_GL(); - if (!surface_is_offscreen((IWineD3DSurface *)This)) + if (!surface_is_offscreen(This)) { - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This); + GLenum buffer = surface_get_gl_buffer(This); TRACE("Unlocking %#x buffer.\n", buffer); context_set_draw_buffer(context, buffer); } @@ -1480,7 +1803,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm { /* Primary offscreen render target */ TRACE("Offscreen render target.\n"); - context_set_draw_buffer(context, myDevice->offscreenBuffer); + context_set_draw_buffer(context, device->offscreenBuffer); } glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store); @@ -1553,7 +1876,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; BOOL fullsurface; if (!(This->Flags & SFLAG_LOCKED)) { @@ -1563,11 +1886,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { if (This->Flags & SFLAG_PBO) { + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; TRACE("Freeing PBO memory\n"); - context = context_acquire(myDevice, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); + gl_info = context->gl_info; + ENTER_GL(); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo)); GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); @@ -1586,7 +1912,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { goto unlock_end; } - if ((This->Flags & SFLAG_SWAPCHAIN) || (myDevice->render_targets && iface == myDevice->render_targets[0])) + if ((This->Flags & SFLAG_SWAPCHAIN) || (device->render_targets && This == device->render_targets[0])) { if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) { static BOOL warned = FALSE; @@ -1633,7 +1959,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { This->dirtyRect.top = This->currentDesc.Height; This->dirtyRect.right = 0; This->dirtyRect.bottom = 0; - } else if(iface == myDevice->stencilBufferTarget) { + } + else if (This == device->depth_stencil) + { FIXME("Depth Stencil buffer locking is not implemented\n"); } else { /* The rest should be a normal texture */ @@ -1643,9 +1971,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { * states need resetting */ if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) { - if(impl->baseTexture.bindCount) { - IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_SAMPLER(impl->baseTexture.sampler)); - } + if (impl->baseTexture.bindCount) + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(impl->baseTexture.sampler)); IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl); } } @@ -1661,35 +1988,34 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { return WINED3D_OK; } -static void surface_release_client_storage(IWineD3DSurface *iface) +static void surface_release_client_storage(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; struct wined3d_context *context; - context = context_acquire(This->resource.device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(surface->resource.device, NULL); ENTER_GL(); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); - if(This->texture_name) + if (surface->texture_name) { - surface_bind_and_dirtify(This, FALSE); - glTexImage2D(This->texture_target, This->texture_level, - GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + surface_bind_and_dirtify(surface, FALSE); + glTexImage2D(surface->texture_target, surface->texture_level, + GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } - if(This->texture_name_srgb) + if (surface->texture_name_srgb) { - surface_bind_and_dirtify(This, TRUE); - glTexImage2D(This->texture_target, This->texture_level, - GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + surface_bind_and_dirtify(surface, TRUE); + glTexImage2D(surface->texture_target, surface->texture_level, + GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); } glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); LEAVE_GL(); context_release(context); - IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE); - IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); - surface_force_reload(iface); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INSRGBTEX, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); + surface_force_reload(surface); } static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) @@ -1720,7 +2046,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD if(!This->hDC) { if(This->Flags & SFLAG_CLIENT) { IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); - surface_release_client_storage(iface); + surface_release_client_storage(This); } hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface); if(FAILED(hr)) return WINED3DERR_INVALIDCALL; @@ -1761,7 +2087,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD IWineD3DSurfaceImpl *dds_primary; IWineD3DSwapChainImpl *swapchain; swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0]; - dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; + dds_primary = swapchain->front_buffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; } @@ -1815,28 +2141,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC IWineD3DSurface Internal (No mapping to directx api) parts follow ****************************************************** */ -HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) { +HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, struct wined3d_format_desc *desc, CONVERT_TYPES *convert) +{ BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT); - const struct GlPixelFormatDesc *glDesc = This->resource.format_desc; IWineD3DDeviceImpl *device = This->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + BOOL blit_supported = FALSE; + RECT rect = {0, 0, This->pow2Width, This->pow2Height}; - /* Default values: From the surface */ - *format = glDesc->glFormat; - *type = glDesc->glType; + /* Copy the default values from the surface. Below we might perform fixups */ + /* TODO: get rid of color keying desc fixups by using e.g. a table. */ + *desc = *This->resource.format_desc; *convert = NO_CONVERSION; - *target_bpp = glDesc->byte_count; - - if(srgb_mode) { - *internal = glDesc->glGammaInternal; - } - else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET - && surface_is_offscreen((IWineD3DSurface *) This)) - { - *internal = glDesc->rtInternal; - } else { - *internal = glDesc->glInternal; - } /* Ok, now look if we have to do any conversion */ switch(This->resource.format_desc->format) @@ -1846,34 +2161,30 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ Paletted Texture **************** */ - /* Use conversion when the paletted texture extension OR fragment shaders are available. When either - * of the two is available make sure texturing is requested as neither of the two works in - * conjunction with calls like glDraw-/glReadPixels. Further also use conversion in case of color keying. + blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &rect, This->resource.usage, This->resource.pool, + This->resource.format_desc, &rect, This->resource.usage, + This->resource.pool, This->resource.format_desc); + + /* Use conversion when the blit_shader backend supports it. It only supports this in case of + * texturing. Further also use conversion in case of color keying. * Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which * conflicts with this. */ - if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup) - && device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0])) + if (!((blit_supported && device->render_targets && This == device->render_targets[0])) || colorkey_active || !use_texturing) { - *format = GL_RGBA; - *internal = GL_RGBA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 4; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGBA; + desc->glType = GL_UNSIGNED_BYTE; + desc->conv_byte_count = 4; if(colorkey_active) { *convert = CONVERT_PALETTED_CK; } else { *convert = CONVERT_PALETTED; } } - else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)) - { - *format = GL_ALPHA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 1; - } - break; case WINED3DFMT_B2G3R3_UNORM: @@ -1890,149 +2201,40 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ case WINED3DFMT_B5G6R5_UNORM: if (colorkey_active) { *convert = CONVERT_CK_565; - *format = GL_RGBA; - *internal = GL_RGB5_A1; - *type = GL_UNSIGNED_SHORT_5_5_5_1; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGB5_A1; + desc->glType = GL_UNSIGNED_SHORT_5_5_5_1; + desc->conv_byte_count = 2; } break; case WINED3DFMT_B5G5R5X1_UNORM: if (colorkey_active) { *convert = CONVERT_CK_5551; - *format = GL_BGRA; - *internal = GL_RGB5_A1; - *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + desc->glFormat = GL_BGRA; + desc->glInternal = GL_RGB5_A1; + desc->glType = GL_UNSIGNED_SHORT_1_5_5_5_REV; + desc->conv_byte_count = 2; } break; case WINED3DFMT_B8G8R8_UNORM: if (colorkey_active) { *convert = CONVERT_CK_RGB24; - *format = GL_RGBA; - *internal = GL_RGBA8; - *type = GL_UNSIGNED_INT_8_8_8_8; - *target_bpp = 4; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGBA8; + desc->glType = GL_UNSIGNED_INT_8_8_8_8; + desc->conv_byte_count = 4; } break; case WINED3DFMT_B8G8R8X8_UNORM: if (colorkey_active) { *convert = CONVERT_RGB32_888; - *format = GL_RGBA; - *internal = GL_RGBA8; - *type = GL_UNSIGNED_INT_8_8_8_8; - } - break; - - case WINED3DFMT_R8G8_SNORM: - if (gl_info->supported[NV_TEXTURE_SHADER]) break; - *convert = CONVERT_V8U8; - *format = GL_BGR; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 3; - break; - - case WINED3DFMT_R5G5_SNORM_L6_UNORM: - *convert = CONVERT_L6V5U5; - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - *target_bpp = 3; - /* Use format and types from table */ - } else { - /* Load it into unsigned R5G6B5, swap L and V channels, and revert that in the shader */ - *target_bpp = 2; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5; - } - break; - - case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: - *convert = CONVERT_X8L8V8U8; - *target_bpp = 4; - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - /* Use formats from gl table. It is a bit unfortunate, but the conversion - * is needed to set the X format to 255 to get 1.0 for alpha when sampling - * the texture. OpenGL can't use GL_DSDT8_MAG8_NV as internal format with - * the needed type and format parameter, so the internal format contains a - * 4th component, which is returned as alpha - */ - } else { - *format = GL_BGRA; - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - break; - - case WINED3DFMT_R8G8B8A8_SNORM: - if (gl_info->supported[NV_TEXTURE_SHADER]) break; - *convert = CONVERT_Q8W8V8U8; - *format = GL_BGRA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 4; - break; - - case WINED3DFMT_R16G16_SNORM: - if (gl_info->supported[NV_TEXTURE_SHADER]) break; - *convert = CONVERT_V16U16; - *format = GL_BGR; - *type = GL_UNSIGNED_SHORT; - *target_bpp = 6; - break; - - case WINED3DFMT_L4A4_UNORM: - /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not - * format+type combination to load it. Thus convert it to A8L8, then load it - * with A4L4 internal, but A8L8 format+type - */ - *convert = CONVERT_A4L4; - *format = GL_LUMINANCE_ALPHA; - *type = GL_UNSIGNED_BYTE; - *target_bpp = 2; - break; - - case WINED3DFMT_R16G16_UNORM: - *convert = CONVERT_G16R16; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT; - *target_bpp = 6; - break; - - case WINED3DFMT_R16G16_FLOAT: - *convert = CONVERT_R16G16F; - *format = GL_RGB; - *type = GL_HALF_FLOAT_ARB; - *target_bpp = 6; - break; - - case WINED3DFMT_R32G32_FLOAT: - *convert = CONVERT_R32G32F; - *format = GL_RGB; - *type = GL_FLOAT; - *target_bpp = 12; - break; - - case WINED3DFMT_S1_UINT_D15_UNORM: - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] - || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) - { - *convert = CONVERT_D15S1; - *target_bpp = 4; - } - break; - - case WINED3DFMT_S4X4_UINT_D24_UNORM: - if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] - || gl_info->supported[EXT_PACKED_DEPTH_STENCIL]) - { - *convert = CONVERT_D24X4S4; - } - break; - - case WINED3DFMT_S8_UINT_D24_FLOAT: - if (gl_info->supported[ARB_DEPTH_BUFFER_FLOAT]) - { - *convert = CONVERT_D24FS8; - *target_bpp = 8; + desc->glFormat = GL_RGBA; + desc->glInternal = GL_RGBA8; + desc->glType = GL_UNSIGNED_INT_8_8_8_8; + desc->conv_byte_count = 4; } break; @@ -2043,7 +2245,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ return WINED3D_OK; } -static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) +void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) { IWineD3DDeviceImpl *device = This->resource.device; IWineD3DPaletteImpl *pal = This->palette; @@ -2126,8 +2328,6 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4] static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This) { - IWineD3DDeviceImpl *device = This->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const BYTE *source; BYTE *dest; TRACE("(%p)->(%p),(%d,%d,%d,%d,%p)\n", src, dst, pitch, height, outpitch, convert,This); @@ -2273,338 +2473,12 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI } break; - case CONVERT_V8U8: - { - unsigned int x, y; - const short *Source; - unsigned char *Dest; - for(y = 0; y < height; y++) { - Source = (const short *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* B */ Dest[0] = 0xff; - /* G */ Dest[1] = (color >> 8) + 128; /* V */ - /* R */ Dest[2] = (color) + 128; /* U */ - Dest += 3; - } - } - break; - } - - case CONVERT_V16U16: - { - unsigned int x, y; - const DWORD *Source; - unsigned short *Dest; - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = (unsigned short *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - DWORD color = (*Source++); - /* B */ Dest[0] = 0xffff; - /* G */ Dest[1] = (color >> 16) + 32768; /* V */ - /* R */ Dest[2] = (color ) + 32768; /* U */ - Dest += 3; - } - } - break; - } - - case CONVERT_Q8W8V8U8: - { - unsigned int x, y; - const DWORD *Source; - unsigned char *Dest; - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ - /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ - Dest += 4; - } - } - break; - } - - case CONVERT_L6V5U5: - { - unsigned int x, y; - const WORD *Source; - unsigned char *Dest; - - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - /* This makes the gl surface bigger(24 bit instead of 16), but it works with - * fixed function and shaders without further conversion once the surface is - * loaded - */ - for(y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - short color = (*Source++); - unsigned char l = ((color >> 10) & 0xfc); - char v = ((color >> 5) & 0x3e); - char u = ((color ) & 0x1f); - - /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign - * and doubles the positive range. Thus shift left only once, gl does the 2nd - * shift. GL reads a signed value and converts it into an unsigned value. - */ - /* M */ Dest[2] = l << 1; - - /* Those are read as signed, but kept signed. Just left-shift 3 times to scale - * from 5 bit values to 8 bit values. - */ - /* V */ Dest[1] = v << 3; - /* U */ Dest[0] = u << 3; - Dest += 3; - } - } - } else { - for(y = 0; y < height; y++) { - unsigned short *Dest_s = (unsigned short *) (dst + y * outpitch); - Source = (const WORD *)(src + y * pitch); - for (x = 0; x < width; x++ ) { - short color = (*Source++); - unsigned char l = ((color >> 10) & 0xfc); - short v = ((color >> 5) & 0x3e); - short u = ((color ) & 0x1f); - short v_conv = v + 16; - short u_conv = u + 16; - - *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); - Dest_s += 1; - } - } - } - break; - } - - case CONVERT_X8L8V8U8: - { - unsigned int x, y; - const DWORD *Source; - unsigned char *Dest; - - if (gl_info->supported[NV_TEXTURE_SHADER]) - { - /* This implementation works with the fixed function pipeline and shaders - * without further modification after converting the surface. - */ - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ - /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ - /* U */ Dest[0] = (color & 0xff); /* U */ - /* I */ Dest[3] = 255; /* X */ - Dest += 4; - } - } - } else { - /* Doesn't work correctly with the fixed function pipeline, but can work in - * shaders if the shader is adjusted. (There's no use for this format in gl's - * standard fixed function pipeline anyway). - */ - for(y = 0; y < height; y++) { - Source = (const DWORD *)(src + y * pitch); - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - long color = (*Source++); - /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ - /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ - /* R */ Dest[2] = (color & 0xff) + 128; /* U */ - Dest += 4; - } - } - } - break; - } - - case CONVERT_A4L4: - { - unsigned int x, y; - const unsigned char *Source; - unsigned char *Dest; - for(y = 0; y < height; y++) { - Source = src + y * pitch; - Dest = dst + y * outpitch; - for (x = 0; x < width; x++ ) { - unsigned char color = (*Source++); - /* A */ Dest[1] = (color & 0xf0) << 0; - /* L */ Dest[0] = (color & 0x0f) << 4; - Dest += 2; - } - } - break; - } - - case CONVERT_G16R16: - case CONVERT_R16G16F: - { - unsigned int x, y; - const WORD *Source; - WORD *Dest; - - for(y = 0; y < height; y++) { - Source = (const WORD *)(src + y * pitch); - Dest = (WORD *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - WORD green = (*Source++); - WORD red = (*Source++); - Dest[0] = green; - Dest[1] = red; - /* Strictly speaking not correct for R16G16F, but it doesn't matter because the - * shader overwrites it anyway - */ - Dest[2] = 0xffff; - Dest += 3; - } - } - break; - } - - case CONVERT_R32G32F: - { - unsigned int x, y; - const float *Source; - float *Dest; - for(y = 0; y < height; y++) { - Source = (const float *)(src + y * pitch); - Dest = (float *) (dst + y * outpitch); - for (x = 0; x < width; x++ ) { - float green = (*Source++); - float red = (*Source++); - Dest[0] = green; - Dest[1] = red; - Dest[2] = 1.0f; - Dest += 3; - } - } - break; - } - - case CONVERT_D15S1: - { - unsigned int x, y; - - for (y = 0; y < height; ++y) - { - const WORD *source = (const WORD *)(src + y * pitch); - DWORD *dest = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) - { - /* The depth data is normalized, so needs to be scaled, - * the stencil data isn't. Scale depth data by - * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ - WORD d15 = source[x] >> 1; - DWORD d24 = (d15 << 9) + (d15 >> 6); - dest[x] = (d24 << 8) | (source[x] & 0x1); - } - } - break; - } - - case CONVERT_D24X4S4: - { - unsigned int x, y; - - for (y = 0; y < height; ++y) - { - const DWORD *source = (const DWORD *)(src + y * pitch); - DWORD *dest = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) - { - /* Just need to clear out the X4 part. */ - dest[x] = source[x] & ~0xf0; - } - } - break; - } - - case CONVERT_D24FS8: - { - unsigned int x, y; - - for (y = 0; y < height; ++y) - { - const DWORD *source = (const DWORD *)(src + y * pitch); - float *dest_f = (float *)(dst + y * outpitch); - DWORD *dest_s = (DWORD *)(dst + y * outpitch); - - for (x = 0; x < width; ++x) - { - dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); - dest_s[x * 2 + 1] = source[x] & 0xff; - } - } - break; - } - default: ERR("Unsupported conversion type %#x.\n", convert); } return WINED3D_OK; } -/* This function is used in case of 8bit paletted textures to upload the palette. - It supports GL_EXT_paletted_texture and GL_ARB_fragment_program, support for other - extensions like ATI_fragment_shaders is possible. -*/ -/* Context activation is done by the caller. */ -static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - BYTE table[256][4]; - IWineD3DDeviceImpl *device = This->resource.device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - - d3dfmt_p8_init_palette(This, table, (convert == CONVERT_PALETTED_CK)); - - /* Try to use the paletted texture extension */ - if (gl_info->supported[EXT_PALETTED_TEXTURE]) - { - TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n"); - ENTER_GL(); - GL_EXTCALL(glColorTableEXT(This->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table)); - LEAVE_GL(); - } - else - { - /* Let a fragment shader do the color conversion by uploading the palette to a 1D texture. - * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */ - TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n"); - - device->blitter->set_shader((IWineD3DDevice *) device, This->resource.format_desc, - This->texture_target, This->pow2Width, This->pow2Height); - - ENTER_GL(); - GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1)); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* Make sure we have discrete color levels. */ - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table); /* Upload the palette */ - - /* Switch back to unit 0 in which the 2D texture will be stored. */ - GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0)); - - /* Rebind the texture because it isn't bound anymore */ - glBindTexture(This->texture_target, This->texture_name); - LEAVE_GL(); - } -} - BOOL palette9_changed(IWineD3DSurfaceImpl *This) { IWineD3DDeviceImpl *device = This->resource.device; @@ -2827,7 +2701,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c LEAVE_GL(); } else { /* bind the real texture, and make sure it up to date */ - surface_internal_preload(iface, SRGB_RGB); + surface_internal_preload(This, SRGB_RGB); surface_bind_and_dirtify(This, FALSE); } allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4); @@ -2948,9 +2822,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); /* For client textures opengl has to be notified */ - if(This->Flags & SFLAG_CLIENT) { - surface_release_client_storage(iface); - } + if (This->Flags & SFLAG_CLIENT) + surface_release_client_storage(This); /* Now free the old memory if any */ HeapFree(GetProcessHeap(), 0, release); @@ -2961,9 +2834,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M if(This->resource.heapMemory != NULL) ERR("User pointer surface has heap memory allocated\n"); This->Flags &= ~SFLAG_USERPTR; - if(This->Flags & SFLAG_CLIENT) { - surface_release_client_storage(iface); - } + if (This->Flags & SFLAG_CLIENT) + surface_release_client_storage(This); } return WINED3D_OK; } @@ -3099,7 +2971,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS } /* Flipping a OpenGL surface -> Use WineD3DDevice::Present */ - hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0); + hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain, + NULL, NULL, swapchain->win_handle, NULL, 0); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } @@ -3107,36 +2980,48 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS /* Does a direct frame buffer -> texture copy. Stretching is done * with single pixel copy calls */ -static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, - const WINED3DRECT *srect, const WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) +static void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *dst_surface, IWineD3DSurfaceImpl *src_surface, + const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = dst_surface->resource.device; float xrel, yrel; UINT row; - IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; struct wined3d_context *context; + BOOL upsidedown = FALSE; + RECT dst_rect = *dst_rect_in; + /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag + * glCopyTexSubImage is a bit picky about the parameters we pass to it + */ + if(dst_rect.top > dst_rect.bottom) { + UINT tmp = dst_rect.bottom; + dst_rect.bottom = dst_rect.top; + dst_rect.top = tmp; + upsidedown = TRUE; + } - context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT); - surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB); + context = context_acquire(device, src_surface); + context_apply_blit_state(context, device); + surface_internal_preload(dst_surface, SRGB_RGB); ENTER_GL(); /* Bind the target texture */ - glBindTexture(This->texture_target, This->texture_name); + glBindTexture(dst_surface->texture_target, dst_surface->texture_name); checkGLcall("glBindTexture"); - if(surface_is_offscreen(SrcSurface)) { + if (surface_is_offscreen(src_surface)) + { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; - glReadBuffer(myDevice->offscreenBuffer); + glReadBuffer(device->offscreenBuffer); } else { - glReadBuffer(surface_get_gl_buffer(SrcSurface)); + glReadBuffer(surface_get_gl_buffer(src_surface)); } checkGLcall("glReadBuffer"); - xrel = (float) (srect->x2 - srect->x1) / (float) (drect->x2 - drect->x1); - yrel = (float) (srect->y2 - srect->y1) / (float) (drect->y2 - drect->y1); + xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left); + yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top); if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) { @@ -3158,19 +3043,19 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D { /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */ - glCopyTexSubImage2D(This->texture_target, This->texture_level, - drect->x1 /*xoffset */, drect->y1 /* y offset */, - srect->x1, Src->currentDesc.Height - srect->y2, - drect->x2 - drect->x1, drect->y2 - drect->y1); + glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, + dst_rect.left /*xoffset */, dst_rect.top /* y offset */, + src_rect->left, src_surface->currentDesc.Height - src_rect->bottom, + dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); } else { - UINT yoffset = Src->currentDesc.Height - srect->y1 + drect->y1 - 1; + UINT yoffset = src_surface->currentDesc.Height - src_rect->top + dst_rect.top - 1; /* I have to process this row by row to swap the image, * otherwise it would be upside down, so stretching in y direction * doesn't cost extra time * * However, stretching in x direction can be avoided if not necessary */ - for(row = drect->y1; row < drect->y2; row++) { + for(row = dst_rect.top; row < dst_rect.bottom; row++) { if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) { /* Well, that stuff works, but it's very slow. @@ -3178,15 +3063,18 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D */ UINT col; - for(col = drect->x1; col < drect->x2; col++) { - glCopyTexSubImage2D(This->texture_target, This->texture_level, - drect->x1 + col /* x offset */, row /* y offset */, - srect->x1 + col * xrel, yoffset - (int) (row * yrel), 1, 1); + for (col = dst_rect.left; col < dst_rect.right; ++col) + { + glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, + dst_rect.left + col /* x offset */, row /* y offset */, + src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1); } - } else { - glCopyTexSubImage2D(This->texture_target, This->texture_level, - drect->x1 /* x offset */, row /* y offset */, - srect->x1, yoffset - (int) (row * yrel), drect->x2-drect->x1, 1); + } + else + { + glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level, + dst_rect.left /* x offset */, row /* y offset */, + src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1); } } } @@ -3198,37 +3086,39 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D /* The texture is now most up to date - If the surface is a render target and has a drawable, this * path is never entered */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INTEXTURE, TRUE); } /* Uses the hardware to stretch and flip the image */ -static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, - IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect, - BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) +static void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *dst_surface, IWineD3DSurfaceImpl *src_surface, + const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = dst_surface->resource.device; GLuint src, backup = 0; - IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; + IWineD3DSwapChainImpl *src_swapchain = NULL; float left, right, top, bottom; /* Texture coordinates */ - UINT fbwidth = Src->currentDesc.Width; - UINT fbheight = Src->currentDesc.Height; + UINT fbwidth = src_surface->currentDesc.Width; + UINT fbheight = src_surface->currentDesc.Height; struct wined3d_context *context; GLenum drawBuffer = GL_BACK; GLenum texture_target; BOOL noBackBufferBackup; BOOL src_offscreen; + BOOL upsidedown = FALSE; + RECT dst_rect = *dst_rect_in; TRACE("Using hwstretch blit\n"); /* Activate the Proper context for reading from the source surface, set it up for blitting */ - context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT); - surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB); + context = context_acquire(device, src_surface); + context_apply_blit_state(context, device); + surface_internal_preload(dst_surface, SRGB_RGB); - src_offscreen = surface_is_offscreen(SrcSurface); + src_offscreen = surface_is_offscreen(src_surface); noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO; - if (!noBackBufferBackup && !Src->texture_name) + if (!noBackBufferBackup && !src_surface->texture_name) { /* Get it a description */ - surface_internal_preload(SrcSurface, SRGB_RGB); + surface_internal_preload(src_surface, SRGB_RGB); } ENTER_GL(); @@ -3240,7 +3130,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine /* Got more than one aux buffer? Use the 2nd aux buffer */ drawBuffer = GL_AUX1; } - else if ((!src_offscreen || myDevice->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1) + else if ((!src_offscreen || device->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1) { /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */ drawBuffer = GL_AUX0; @@ -3256,25 +3146,35 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If * we are reading from the back buffer, the backup can be used as source texture */ - texture_target = Src->texture_target; - glBindTexture(texture_target, Src->texture_name); - checkGLcall("glBindTexture(texture_target, Src->texture_name)"); + texture_target = src_surface->texture_target; + glBindTexture(texture_target, src_surface->texture_name); + checkGLcall("glBindTexture(texture_target, src_surface->texture_name)"); glEnable(texture_target); checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ - Src->Flags &= ~SFLAG_INTEXTURE; + src_surface->Flags &= ~SFLAG_INTEXTURE; + } + + /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag + * glCopyTexSubImage is a bit picky about the parameters we pass to it + */ + if(dst_rect.top > dst_rect.bottom) { + UINT tmp = dst_rect.bottom; + dst_rect.bottom = dst_rect.top; + dst_rect.top = tmp; + upsidedown = TRUE; } if (src_offscreen) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; - glReadBuffer(myDevice->offscreenBuffer); + glReadBuffer(device->offscreenBuffer); } else { - glReadBuffer(surface_get_gl_buffer(SrcSurface)); + glReadBuffer(surface_get_gl_buffer(src_surface)); } /* TODO: Only back up the part that will be overwritten */ @@ -3294,9 +3194,14 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE)); checkGLcall("glTexParameteri"); - if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) { - src = backup ? backup : Src->texture_name; - } else { + IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&src_swapchain); + if (src_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)src_swapchain); + if (!src_swapchain || src_surface == src_swapchain->back_buffers[0]) + { + src = backup ? backup : src_surface->texture_name; + } + else + { glReadBuffer(GL_FRONT); checkGLcall("glReadBuffer(GL_FRONT)"); @@ -3305,11 +3210,11 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine glBindTexture(GL_TEXTURE_2D, src); checkGLcall("glBindTexture(GL_TEXTURE_2D, src)"); - /* TODO: Only copy the part that will be read. Use srect->x1, srect->y2 as origin, but with the width watch + /* TODO: Only copy the part that will be read. Use src_rect->left, src_rect->bottom as origin, but with the width watch * out for power of 2 sizes */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Src->pow2Width, Src->pow2Height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_surface->pow2Width, + src_surface->pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); checkGLcall("glTexImage2D"); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0 /* read offsets */, @@ -3333,22 +3238,26 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine } checkGLcall("glEnd and previous"); - left = srect->x1; - right = srect->x2; + left = src_rect->left; + right = src_rect->right; - if(upsidedown) { - top = Src->currentDesc.Height - srect->y1; - bottom = Src->currentDesc.Height - srect->y2; - } else { - top = Src->currentDesc.Height - srect->y2; - bottom = Src->currentDesc.Height - srect->y1; + if (upsidedown) + { + top = src_surface->currentDesc.Height - src_rect->top; + bottom = src_surface->currentDesc.Height - src_rect->bottom; + } + else + { + top = src_surface->currentDesc.Height - src_rect->bottom; + bottom = src_surface->currentDesc.Height - src_rect->top; } - if(Src->Flags & SFLAG_NORMCOORD) { - left /= Src->pow2Width; - right /= Src->pow2Width; - top /= Src->pow2Height; - bottom /= Src->pow2Height; + if (src_surface->Flags & SFLAG_NORMCOORD) + { + left /= src_surface->pow2Width; + right /= src_surface->pow2Width; + top /= src_surface->pow2Height; + bottom /= src_surface->pow2Height; } /* draw the source texture stretched and upside down. The correct surface is bound already */ @@ -3365,33 +3274,33 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine /* top left */ glTexCoord2f(left, top); - glVertex2i(0, fbheight - drect->y2 - drect->y1); + glVertex2i(0, fbheight - dst_rect.bottom - dst_rect.top); /* top right */ glTexCoord2f(right, top); - glVertex2i(drect->x2 - drect->x1, fbheight - drect->y2 - drect->y1); + glVertex2i(dst_rect.right - dst_rect.left, fbheight - dst_rect.bottom - dst_rect.top); /* bottom right */ glTexCoord2f(right, bottom); - glVertex2i(drect->x2 - drect->x1, fbheight); + glVertex2i(dst_rect.right - dst_rect.left, fbheight); glEnd(); checkGLcall("glEnd and previous"); - if (texture_target != This->texture_target) + if (texture_target != dst_surface->texture_target) { glDisable(texture_target); - glEnable(This->texture_target); - texture_target = This->texture_target; + glEnable(dst_surface->texture_target); + texture_target = dst_surface->texture_target; } /* Now read the stretched and upside down image into the destination texture */ - glBindTexture(texture_target, This->texture_name); + glBindTexture(texture_target, dst_surface->texture_name); checkGLcall("glBindTexture"); glCopyTexSubImage2D(texture_target, 0, - drect->x1, drect->y1, /* xoffset, yoffset */ + dst_rect.left, dst_rect.top, /* xoffset, yoffset */ 0, 0, /* We blitted the image to the origin */ - drect->x2 - drect->x1, drect->y2 - drect->y1); + dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); checkGLcall("glCopyTexSubImage2D"); if(drawBuffer == GL_BACK) { @@ -3404,20 +3313,22 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine } glBindTexture(GL_TEXTURE_2D, backup); checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)"); - } else { - if (texture_target != Src->texture_target) + } + else + { + if (texture_target != src_surface->texture_target) { glDisable(texture_target); - glEnable(Src->texture_target); - texture_target = Src->texture_target; + glEnable(src_surface->texture_target); + texture_target = src_surface->texture_target; } - glBindTexture(Src->texture_target, Src->texture_name); - checkGLcall("glBindTexture(Src->texture_target, Src->texture_name)"); + glBindTexture(src_surface->texture_target, src_surface->texture_name); + checkGLcall("glBindTexture(src_surface->texture_target, src_surface->texture_name)"); } glBegin(GL_QUADS); /* top left */ - glTexCoord2f(0.0f, (float)fbheight / (float)Src->pow2Height); + glTexCoord2f(0.0f, (float)fbheight / (float)src_surface->pow2Height); glVertex2i(0, 0); /* bottom left */ @@ -3425,11 +3336,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine glVertex2i(0, fbheight); /* bottom right */ - glTexCoord2f((float)fbwidth / (float)Src->pow2Width, 0.0f); - glVertex2i(fbwidth, Src->currentDesc.Height); + glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, 0.0f); + glVertex2i(fbwidth, src_surface->currentDesc.Height); /* top right */ - glTexCoord2f((float) fbwidth / (float) Src->pow2Width, (float) fbheight / (float) Src->pow2Height); + glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, + (float)fbheight / (float)src_surface->pow2Height); glVertex2i(fbwidth, 0); glEnd(); } @@ -3437,7 +3349,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine checkGLcall("glDisable(texture_target)"); /* Cleanup */ - if (src != Src->texture_name && src != backup) + if (src != src_surface->texture_name && src != backup) { glDeleteTextures(1, &src); checkGLcall("glDeleteTextures(1, &src)"); @@ -3449,48 +3361,76 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); /* The texture is now most up to date - If the surface is a render target and has a drawable, this * path is never entered */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INTEXTURE, TRUE); +} + +/* Until the blit_shader is ready, define some prototypes here. */ +static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc); + +/* Front buffer coordinates are always full screen coordinates, but our GL + * drawable is limited to the window's client area. The sysmem and texture + * copies do have the full screen size. Note that GL has a bottom-left + * origin, while D3D has a top-left origin. */ +void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) +{ + POINT offset = {0, surface->currentDesc.Height}; + RECT windowsize; + + GetClientRect(window, &windowsize); + offset.y -= windowsize.bottom - windowsize.top; + ScreenToClient(window, &offset); + OffsetRect(rect, offset.x, offset.y); } /* Not called from the VTable */ -static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const RECT *DestRect, - IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, +static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface, const RECT *DestRect, + IWineD3DSurfaceImpl *src_surface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { - IWineD3DDeviceImpl *myDevice = This->resource.device; - WINED3DRECT rect; + IWineD3DDeviceImpl *device = dst_surface->resource.device; IWineD3DSwapChainImpl *srcSwapchain = NULL, *dstSwapchain = NULL; - IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; + RECT dst_rect, src_rect; - TRACE("(%p)->(%p,%p,%p,%08x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx); + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(DestRect), src_surface, wine_dbgstr_rect(SrcRect), + Flags, DDBltFx, debug_d3dtexturefiltertype(Filter)); /* Get the swapchain. One of the surfaces has to be a primary surface */ - if(This->resource.pool == WINED3DPOOL_SYSTEMMEM) { + if (dst_surface->resource.pool == WINED3DPOOL_SYSTEMMEM) + { WARN("Destination is in sysmem, rejecting gl blt\n"); return WINED3DERR_INVALIDCALL; } - IWineD3DSurface_GetContainer( (IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&dstSwapchain); - if(dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) dstSwapchain); - if(Src) { - if(Src->resource.pool == WINED3DPOOL_SYSTEMMEM) { + IWineD3DSurface_GetContainer((IWineD3DSurface *)dst_surface, &IID_IWineD3DSwapChain, (void **)&dstSwapchain); + if (dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)dstSwapchain); + if (src_surface) + { + if (src_surface->resource.pool == WINED3DPOOL_SYSTEMMEM) + { WARN("Src is in sysmem, rejecting gl blt\n"); return WINED3DERR_INVALIDCALL; } - IWineD3DSurface_GetContainer( (IWineD3DSurface *) Src, &IID_IWineD3DSwapChain, (void **)&srcSwapchain); - if(srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) srcSwapchain); + IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&srcSwapchain); + if (srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)srcSwapchain); } /* Early sort out of cases where no render target is used */ - if(!dstSwapchain && !srcSwapchain && - SrcSurface != myDevice->render_targets[0] && This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) { - TRACE("No surface is render target, not using hardware blit. Src = %p, dst = %p\n", Src, This); + if (!dstSwapchain && !srcSwapchain + && src_surface != device->render_targets[0] + && dst_surface != device->render_targets[0]) + { + TRACE("No surface is render target, not using hardware blit.\n"); return WINED3DERR_INVALIDCALL; } @@ -3501,21 +3441,14 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const return WINED3DERR_INVALIDCALL; } - if (DestRect) { - rect.x1 = DestRect->left; - rect.y1 = DestRect->top; - rect.x2 = DestRect->right; - rect.y2 = DestRect->bottom; - } else { - rect.x1 = 0; - rect.y1 = 0; - rect.x2 = This->currentDesc.Width; - rect.y2 = This->currentDesc.Height; - } + surface_get_rect(dst_surface, DestRect, &dst_rect); + if (src_surface) surface_get_rect(src_surface, SrcRect, &src_rect); /* The only case where both surfaces on a swapchain are supported is a back buffer -> front buffer blit on the same swapchain */ - if(dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->backBuffer && - ((IWineD3DSurface *) This == dstSwapchain->frontBuffer) && SrcSurface == dstSwapchain->backBuffer[0]) { + if (dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->back_buffers + && dst_surface == dstSwapchain->front_buffer + && src_surface == dstSwapchain->back_buffers[0]) + { /* Half-life does a Blt from the back buffer to the front buffer, * Full surface size, no flags... Use present instead * @@ -3525,57 +3458,50 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Check rects - IWineD3DDevice_Present doesn't handle them */ while(1) { - RECT mySrcRect; TRACE("Looking if a Present can be done...\n"); /* Source Rectangle must be full surface */ - if( SrcRect ) { - if(SrcRect->left != 0 || SrcRect->top != 0 || - SrcRect->right != Src->currentDesc.Width || SrcRect->bottom != Src->currentDesc.Height) { - TRACE("No, Source rectangle doesn't match\n"); - break; - } + if (src_rect.left || src_rect.top + || src_rect.right != src_surface->currentDesc.Width + || src_rect.bottom != src_surface->currentDesc.Height) + { + TRACE("No, Source rectangle doesn't match\n"); + break; } - mySrcRect.left = 0; - mySrcRect.top = 0; - mySrcRect.right = Src->currentDesc.Width; - mySrcRect.bottom = Src->currentDesc.Height; /* No stretching may occur */ - if(mySrcRect.right != rect.x2 - rect.x1 || - mySrcRect.bottom != rect.y2 - rect.y1) { + if(src_rect.right != dst_rect.right - dst_rect.left || + src_rect.bottom != dst_rect.bottom - dst_rect.top) { TRACE("No, stretching is done\n"); break; } /* Destination must be full surface or match the clipping rectangle */ - if(This->clipper && ((IWineD3DClipperImpl *) This->clipper)->hWnd) + if (dst_surface->clipper && ((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd) { RECT cliprect; POINT pos[2]; - GetClientRect(((IWineD3DClipperImpl *) This->clipper)->hWnd, &cliprect); - pos[0].x = rect.x1; - pos[0].y = rect.y1; - pos[1].x = rect.x2; - pos[1].y = rect.y2; - MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *) This->clipper)->hWnd, - pos, 2); + GetClientRect(((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd, &cliprect); + pos[0].x = dst_rect.left; + pos[0].y = dst_rect.top; + pos[1].x = dst_rect.right; + pos[1].y = dst_rect.bottom; + MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *)dst_surface->clipper)->hWnd, pos, 2); if(pos[0].x != cliprect.left || pos[0].y != cliprect.top || pos[1].x != cliprect.right || pos[1].y != cliprect.bottom) { TRACE("No, dest rectangle doesn't match(clipper)\n"); - TRACE("Clip rect at (%d,%d)-(%d,%d)\n", cliprect.left, cliprect.top, cliprect.right, cliprect.bottom); - TRACE("Blt dest: (%d,%d)-(%d,%d)\n", rect.x1, rect.y1, rect.x2, rect.y2); + TRACE("Clip rect at %s\n", wine_dbgstr_rect(&cliprect)); + TRACE("Blt dest: %s\n", wine_dbgstr_rect(&dst_rect)); break; } } - else + else if (dst_rect.left || dst_rect.top + || dst_rect.right != dst_surface->currentDesc.Width + || dst_rect.bottom != dst_surface->currentDesc.Height) { - if(rect.x1 != 0 || rect.y1 != 0 || - rect.x2 != This->currentDesc.Width || rect.y2 != This->currentDesc.Height) { - TRACE("No, dest rectangle doesn't match(surface size)\n"); - break; - } + TRACE("No, dest rectangle doesn't match(surface size)\n"); + break; } TRACE("Yes\n"); @@ -3603,7 +3529,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const dstSwapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE; TRACE("Full screen back buffer -> front buffer blt, performing a flip instead\n"); - IWineD3DSwapChain_Present((IWineD3DSwapChain *) dstSwapchain, NULL, NULL, 0, NULL, 0); + IWineD3DSwapChain_Present((IWineD3DSwapChain *)dstSwapchain, + NULL, NULL, dstSwapchain->win_handle, NULL, 0); dstSwapchain->presentParms.SwapEffect = orig_swap; @@ -3620,21 +3547,31 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const } else if(dstSwapchain && srcSwapchain) { FIXME("Implement hardware blit between two different swapchains\n"); return WINED3DERR_INVALIDCALL; - } else if(dstSwapchain) { - if(SrcSurface == myDevice->render_targets[0]) { + } + else if (dstSwapchain) + { + /* Handled with regular texture -> swapchain blit */ + if (src_surface == device->render_targets[0]) TRACE("Blit from active render target to a swapchain\n"); - /* Handled with regular texture -> swapchain blit */ - } - } else if(srcSwapchain && This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) { + } + else if (srcSwapchain && dst_surface == device->render_targets[0]) + { FIXME("Implement blit from a swapchain to the active render target\n"); return WINED3DERR_INVALIDCALL; } - if((srcSwapchain || SrcSurface == myDevice->render_targets[0]) && !dstSwapchain) { + if ((srcSwapchain || src_surface == device->render_targets[0]) && !dstSwapchain) + { /* Blit from render target to texture */ - WINED3DRECT srect; - BOOL upsideDown, stretchx; - BOOL paletteOverride = FALSE; + BOOL stretchx; + + /* P8 read back is not implemented */ + if (src_surface->resource.format_desc->format == WINED3DFMT_P8_UINT + || dst_surface->resource.format_desc->format == WINED3DFMT_P8_UINT) + { + TRACE("P8 read back not supported by frame buffer to texture blit\n"); + return WINED3DERR_INVALIDCALL; + } if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) { TRACE("Color keying not supported by frame buffer to texture blit\n"); @@ -3642,50 +3579,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Destination color key is checked above */ } - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag - * glCopyTexSubImage is a bit picky about the parameters we pass to it - */ - if(SrcRect) { - if(SrcRect->top < SrcRect->bottom) { - srect.y1 = SrcRect->top; - srect.y2 = SrcRect->bottom; - upsideDown = FALSE; - } else { - srect.y1 = SrcRect->bottom; - srect.y2 = SrcRect->top; - upsideDown = TRUE; - } - srect.x1 = SrcRect->left; - srect.x2 = SrcRect->right; - } else { - srect.x1 = 0; - srect.y1 = 0; - srect.x2 = Src->currentDesc.Width; - srect.y2 = Src->currentDesc.Height; - upsideDown = FALSE; - } - if(rect.x1 > rect.x2) { - UINT tmp = rect.x2; - rect.x2 = rect.x1; - rect.x1 = tmp; - upsideDown = !upsideDown; - } - - if(rect.x2 - rect.x1 != srect.x2 - srect.x1) { + if(dst_rect.right - dst_rect.left != src_rect.right - src_rect.left) { stretchx = TRUE; } else { stretchx = FALSE; } - /* When blitting from a render target a texture, the texture isn't required to have a palette. - * In this case grab the palette from the render target. */ - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !This->palette) - { - paletteOverride = TRUE; - TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This); - This->palette = Src->palette; - } - /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot * flip the image nor scale it. * @@ -3701,92 +3600,66 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering * backends. */ - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer - && surface_can_stretch_rect(Src, This)) + if (fbo_blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format_desc)) + { + stretch_rect_fbo(device, src_surface, &src_rect, dst_surface, &dst_rect, Filter); + } + else if (!stretchx || dst_rect.right - dst_rect.left > src_surface->currentDesc.Width + || dst_rect.bottom - dst_rect.top > src_surface->currentDesc.Height) { - stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect, - (IWineD3DSurface *)This, &rect, Filter, upsideDown); - } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width || - rect.y2 - rect.y1 > Src->currentDesc.Height) { TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n"); - fb_copy_to_texture_direct(This, SrcSurface, &srect, &rect, upsideDown, Filter); + fb_copy_to_texture_direct(dst_surface, src_surface, &src_rect, &dst_rect, Filter); } else { TRACE("Using hardware stretching to flip / stretch the texture\n"); - fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter); + fb_copy_to_texture_hwstretch(dst_surface, src_surface, &src_rect, &dst_rect, Filter); } - /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ - if(paletteOverride) - This->palette = NULL; - - if(!(This->Flags & SFLAG_DONOTFREE)) { - HeapFree(GetProcessHeap(), 0, This->resource.heapMemory); - This->resource.allocatedMemory = NULL; - This->resource.heapMemory = NULL; - } else { - This->Flags &= ~SFLAG_INSYSMEM; + if (!(dst_surface->Flags & SFLAG_DONOTFREE)) + { + HeapFree(GetProcessHeap(), 0, dst_surface->resource.heapMemory); + dst_surface->resource.allocatedMemory = NULL; + dst_surface->resource.heapMemory = NULL; + } + else + { + dst_surface->Flags &= ~SFLAG_INSYSMEM; } return WINED3D_OK; - } else if(Src) { + } + else if (src_surface) + { /* Blit from offscreen surface to render target */ - float glTexCoord[4]; - DWORD oldCKeyFlags = Src->CKeyFlags; - WINEDDCOLORKEY oldBltCKey = Src->SrcBltCKey; + DWORD oldCKeyFlags = src_surface->CKeyFlags; + WINEDDCOLORKEY oldBltCKey = src_surface->SrcBltCKey; struct wined3d_context *context; - RECT SourceRectangle; - BOOL paletteOverride = FALSE; - TRACE("Blt from surface %p to rendertarget %p\n", Src, This); + TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface); - if(SrcRect) { - SourceRectangle.left = SrcRect->left; - SourceRectangle.right = SrcRect->right; - SourceRectangle.top = SrcRect->top; - SourceRectangle.bottom = SrcRect->bottom; - } else { - SourceRectangle.left = 0; - SourceRectangle.right = Src->currentDesc.Width; - SourceRectangle.top = 0; - SourceRectangle.bottom = Src->currentDesc.Height; - } - - /* When blitting from an offscreen surface to a rendertarget, the source - * surface is not required to have a palette. Our rendering / conversion - * code further down the road retrieves the palette from the surface, so - * it must have a palette set. */ - if (Src->resource.format_desc->format == WINED3DFMT_P8_UINT && !Src->palette) - { - paletteOverride = TRUE; - TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This); - Src->palette = This->palette; - } - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer - && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) - && surface_can_stretch_rect(Src, This)) + if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) + && fbo_blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, + src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) { TRACE("Using stretch_rect_fbo\n"); /* The source is always a texture, but never the currently active render target, and the texture - * contents are never upside down - */ - stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, (WINED3DRECT *) &SourceRectangle, - (IWineD3DSurface *)This, &rect, Filter, FALSE); - - /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ - if(paletteOverride) - Src->palette = NULL; + * contents are never upside down. */ + stretch_rect_fbo(device, src_surface, &src_rect, dst_surface, &dst_rect, Filter); return WINED3D_OK; } - if(!CalculateTexRect(Src, &SourceRectangle, glTexCoord)) { - /* Fall back to software */ - WARN("(%p) Source texture area (%d,%d)-(%d,%d) is too big\n", Src, - SourceRectangle.left, SourceRectangle.top, - SourceRectangle.right, SourceRectangle.bottom); - return WINED3DERR_INVALIDCALL; + if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) + && arbfp_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, + src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) + { + return arbfp_blit_surface(device, src_surface, &src_rect, dst_surface, &dst_rect, BLIT_OP_BLIT, Filter); } /* Color keying: Check if we have to do a color keyed blt, @@ -3800,72 +3673,35 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Use color key from surface */ } else if(Flags & WINEDDBLT_KEYSRCOVERRIDE) { /* Use color key from DDBltFx */ - Src->CKeyFlags |= WINEDDSD_CKSRCBLT; - Src->SrcBltCKey = DDBltFx->ddckSrcColorkey; + src_surface->CKeyFlags |= WINEDDSD_CKSRCBLT; + src_surface->SrcBltCKey = DDBltFx->ddckSrcColorkey; } else { /* Do not use color key */ - Src->CKeyFlags &= ~WINEDDSD_CKSRCBLT; + src_surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT; } /* Now load the surface */ - surface_internal_preload((IWineD3DSurface *) Src, SRGB_RGB); + surface_internal_preload(src_surface, SRGB_RGB); /* Activate the destination context, set it up for blitting */ - context = context_acquire(myDevice, (IWineD3DSurface *)This, CTXUSAGE_BLIT); + context = context_acquire(device, dst_surface); + context_apply_blit_state(context, device); - /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates', - * while OpenGL coordinates are window relative. - * Also beware of the origin difference(top left vs bottom left). - * Also beware that the front buffer's surface size is screen width x screen height, - * whereas the real gl drawable size is the size of the window. - */ - if (dstSwapchain && (IWineD3DSurface *)This == dstSwapchain->frontBuffer) { - RECT windowsize; - POINT offset = {0,0}; - UINT h; - ClientToScreen(dstSwapchain->win_handle, &offset); - GetClientRect(dstSwapchain->win_handle, &windowsize); - h = windowsize.bottom - windowsize.top; - rect.x1 -= offset.x; rect.x2 -=offset.x; - rect.y1 -= offset.y; rect.y2 -=offset.y; - rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h; - } + if (dstSwapchain && dst_surface == dstSwapchain->front_buffer) + surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); - if (!is_identity_fixup(This->resource.format_desc->color_fixup)) + if (!device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format_desc, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format_desc)) { - FIXME("Destination format %s has a fixup, this is not supported.\n", - debug_d3dformat(This->resource.format_desc->format)); - dump_color_fixup_desc(This->resource.format_desc->color_fixup); + FIXME("Unsupported blit operation falling back to software\n"); + return WINED3DERR_INVALIDCALL; } - if (!myDevice->blitter->color_fixup_supported(Src->resource.format_desc->color_fixup)) - { - FIXME("Source format %s has an unsupported fixup:\n", - debug_d3dformat(Src->resource.format_desc->format)); - dump_color_fixup_desc(Src->resource.format_desc->color_fixup); - } - - myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format_desc, - Src->texture_target, Src->pow2Width, Src->pow2Height); + device->blitter->set_shader((IWineD3DDevice *)device, src_surface); ENTER_GL(); - /* Bind the texture */ - glBindTexture(Src->texture_target, Src->texture_name); - checkGLcall("glBindTexture"); - - /* Filtering for StretchRect */ - glTexParameteri(Src->texture_target, GL_TEXTURE_MAG_FILTER, - wined3d_gl_mag_filter(magLookup, Filter)); - checkGLcall("glTexParameteri"); - glTexParameteri(Src->texture_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE)); - checkGLcall("glTexParameteri"); - glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - checkGLcall("glTexEnvi"); - /* This is for color keying */ if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) { glEnable(GL_ALPHA_TEST); @@ -3874,8 +3710,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* When the primary render target uses P8, the alpha component contains the palette index. * Which means that the colorkey is one of the palette entries. In other cases pixels that * should be masked away have alpha set to 0. */ - if(primary_render_target_is_p8(myDevice)) - glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0f); + if (primary_render_target_is_p8(device)) + glAlphaFunc(GL_NOTEQUAL, (float)src_surface->SrcBltCKey.dwColorSpaceLowValue / 256.0f); else glAlphaFunc(GL_NOTEQUAL, 0.0f); checkGLcall("glAlphaFunc"); @@ -3886,46 +3722,26 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* Draw a textured quad */ - glBegin(GL_QUADS); - - glColor3f(1.0f, 1.0f, 1.0f); - glTexCoord2f(glTexCoord[0], glTexCoord[2]); - glVertex3f(rect.x1, rect.y1, 0.0f); - - glTexCoord2f(glTexCoord[0], glTexCoord[3]); - glVertex3f(rect.x1, rect.y2, 0.0f); - - glTexCoord2f(glTexCoord[1], glTexCoord[3]); - glVertex3f(rect.x2, rect.y2, 0.0f); - - glTexCoord2f(glTexCoord[1], glTexCoord[2]); - glVertex3f(rect.x2, rect.y1, 0.0f); - - glEnd(); - checkGLcall("glEnd"); + draw_textured_quad(src_surface, &src_rect, &dst_rect, Filter); if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) { glDisable(GL_ALPHA_TEST); checkGLcall("glDisable(GL_ALPHA_TEST)"); } - glBindTexture(Src->texture_target, 0); - checkGLcall("glBindTexture(Src->texture_target, 0)"); - /* Restore the color key parameters */ - Src->CKeyFlags = oldCKeyFlags; - Src->SrcBltCKey = oldBltCKey; - - /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ - if(paletteOverride) - Src->palette = NULL; + src_surface->CKeyFlags = oldCKeyFlags; + src_surface->SrcBltCKey = oldBltCKey; LEAVE_GL(); /* Leave the opengl state valid for blitting */ - myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice); + device->blitter->unset_shader((IWineD3DDevice *)device); - wglFlush(); /* Flush to ensure ordering across contexts. */ + if (wined3d_settings.strict_draw_ordering || (dstSwapchain + && (dst_surface == dstSwapchain->front_buffer + || dstSwapchain->num_contexts > 1))) + wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); @@ -3933,74 +3749,40 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture * is outdated now */ - IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); return WINED3D_OK; } else { /* Source-Less Blit to render target */ if (Flags & WINEDDBLT_COLORFILL) { - /* This is easy to handle for the D3D Device... */ DWORD color; TRACE("Colorfill\n"); - /* This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0] || dstSwapchain - must be true if we are here */ - if (This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0] && - !(This == (IWineD3DSurfaceImpl*) dstSwapchain->frontBuffer || - (dstSwapchain->backBuffer && This == (IWineD3DSurfaceImpl*) dstSwapchain->backBuffer[0]))) { - TRACE("Surface is higher back buffer, falling back to software\n"); - return WINED3DERR_INVALIDCALL; - } - /* The color as given in the Blt function is in the format of the frame-buffer... * 'clear' expect it in ARGB format => we need to do some conversion :-) */ - if (This->resource.format_desc->format == WINED3DFMT_P8_UINT) + if (!surface_convert_color_to_argb(dst_surface, DDBltFx->u5.dwFillColor, &color)) { - DWORD alpha; - - if (primary_render_target_is_p8(myDevice)) alpha = DDBltFx->u5.dwFillColor << 24; - else alpha = 0xFF000000; - - if (This->palette) { - color = (alpha | - (This->palette->palents[DDBltFx->u5.dwFillColor].peRed << 16) | - (This->palette->palents[DDBltFx->u5.dwFillColor].peGreen << 8) | - (This->palette->palents[DDBltFx->u5.dwFillColor].peBlue)); - } else { - color = alpha; - } - } - else if (This->resource.format_desc->format == WINED3DFMT_B5G6R5_UNORM) - { - if (DDBltFx->u5.dwFillColor == 0xFFFF) { - color = 0xFFFFFFFF; - } else { - color = ((0xFF000000) | - ((DDBltFx->u5.dwFillColor & 0xF800) << 8) | - ((DDBltFx->u5.dwFillColor & 0x07E0) << 5) | - ((DDBltFx->u5.dwFillColor & 0x001F) << 3)); - } - } - else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8_UNORM - || This->resource.format_desc->format == WINED3DFMT_B8G8R8X8_UNORM) - { - color = 0xFF000000 | DDBltFx->u5.dwFillColor; - } - else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8A8_UNORM) - { - color = DDBltFx->u5.dwFillColor; - } - else { - ERR("Wrong surface type for BLT override(Format doesn't match) !\n"); + /* The color conversion function already prints an error, so need to do it here */ return WINED3DERR_INVALIDCALL; } - TRACE("(%p) executing Render Target override, color = %x\n", This, color); - IWineD3DDeviceImpl_ClearSurface(myDevice, This, 1 /* Number of rectangles */, - &rect, WINED3DCLEAR_TARGET, color, 0.0f /* Z */, 0 /* Stencil */); - return WINED3D_OK; + if (ffp_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_COLOR_FILL, + NULL, 0, 0, NULL, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) + { + return ffp_blit.color_fill(device, dst_surface, &dst_rect, color); + } + else if (cpu_blit.blit_supported(&device->adapter->gl_info, BLIT_OP_COLOR_FILL, + NULL, 0, 0, NULL, + &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, + dst_surface->resource.format_desc)) + { + return cpu_blit.color_fill(device, dst_surface, &dst_rect, color); + } + return WINED3DERR_INVALIDCALL; } } @@ -4012,7 +3794,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *DestRect, IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx) { - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; float depth; if (Flags & WINEDDBLT_DEPTHFILL) { @@ -4036,13 +3818,8 @@ static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *D ERR("Unexpected format for depth fill: %s\n", debug_d3dformat(This->resource.format_desc->format)); } - return IWineD3DDevice_Clear((IWineD3DDevice *) myDevice, - DestRect == NULL ? 0 : 1, - (const WINED3DRECT *)DestRect, - WINED3DCLEAR_ZBUFFER, - 0x00000000, - depth, - 0x00000000); + return IWineD3DDevice_Clear((IWineD3DDevice *)device, DestRect ? 1 : 0, (const WINED3DRECT *)DestRect, + WINED3DCLEAR_ZBUFFER, 0x00000000, depth, 0x00000000); } FIXME("(%p): Unsupp depthstencil blit\n", This); @@ -4053,7 +3830,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx); TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage)); @@ -4067,8 +3844,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT /* Accessing the depth stencil is supposed to fail between a BeginScene and EndScene pair, * except depth blits, which seem to work */ - if(iface == myDevice->stencilBufferTarget || (SrcSurface && SrcSurface == myDevice->stencilBufferTarget)) { - if(myDevice->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) { + if (This == device->depth_stencil || (Src && Src == device->depth_stencil)) + { + if (device->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) + { TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } else if(IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx) == WINED3D_OK) { @@ -4078,9 +3857,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT } /* Special cases for RenderTargets */ - if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) || - ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) { - if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK; + if ((This->resource.usage & WINED3DUSAGE_RENDERTARGET) + || (Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET))) + { + if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(This, DestRect, Src, SrcRect, Flags, DDBltFx, Filter))) + return WINED3D_OK; } /* For the rest call the X11 surface implementation. @@ -4095,7 +3876,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DSurfaceImpl *srcImpl = (IWineD3DSurfaceImpl *) Source; - IWineD3DDeviceImpl *myDevice = This->resource.device; + IWineD3DDeviceImpl *device = This->resource.device; TRACE("(%p)->(%d, %d, %p, %p, %08x\n", iface, dstx, dsty, Source, rsrc, trans); @@ -4105,9 +3886,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD return WINEDDERR_SURFACEBUSY; } - if(myDevice->inScene && - (iface == myDevice->stencilBufferTarget || - (Source == myDevice->stencilBufferTarget))) { + if (device->inScene && (This == device->depth_stencil || srcImpl == device->depth_stencil)) + { TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } @@ -4119,17 +3899,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD RECT SrcRect, DstRect; DWORD Flags=0; - if(rsrc) { - SrcRect.left = rsrc->left; - SrcRect.top= rsrc->top; - SrcRect.bottom = rsrc->bottom; - SrcRect.right = rsrc->right; - } else { - SrcRect.left = 0; - SrcRect.top = 0; - SrcRect.right = srcImpl->currentDesc.Width; - SrcRect.bottom = srcImpl->currentDesc.Height; - } + surface_get_rect(srcImpl, rsrc, &SrcRect); DstRect.left = dstx; DstRect.top=dsty; @@ -4146,7 +3916,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD if(trans & WINEDDBLTFAST_DONOTWAIT) Flags |= WINEDDBLT_DONOTWAIT; - if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL, WINED3DTEXF_POINT) == WINED3D_OK) return WINED3D_OK; + if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(This, + &DstRect, srcImpl, &SrcRect, Flags, NULL, WINED3DTEXF_POINT))) + return WINED3D_OK; } @@ -4166,31 +3938,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) if (This->resource.format_desc->format == WINED3DFMT_P8_UINT || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - int bpp; - GLenum format, internal, type; - CONVERT_TYPES convert; - - /* Check if we are using a RTL mode which uses texturing for uploads */ - BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX); - - /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */ - d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE); - - if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION)) + if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { - IWineD3DDeviceImpl *device = This->resource.device; - struct wined3d_context *context; - /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */ IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL); /* We want to force a palette refresh, so mark the drawable as not being up to date */ IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE); - - /* Re-upload the palette */ - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); - d3dfmt_p8_upload_palette(iface, convert); - context_release(context); } else { if(!(This->Flags & SFLAG_INSYSMEM)) { TRACE("Palette changed with surface that does not have an up to date system memory copy\n"); @@ -4269,18 +4023,18 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { 3: WARN and return WINED3DERR_NOTAVAILABLE; 4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target. */ - WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n", - This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height); - This->Flags |= SFLAG_OVERSIZE; + if(This->resource.pool == WINED3DPOOL_DEFAULT || This->resource.pool == WINED3DPOOL_MANAGED) + { + WARN("(%p) Unable to allocate a surface which exceeds the maximum OpenGL texture size\n", This); + return WINED3DERR_NOTAVAILABLE; + } - /* This will be initialized on the first blt */ - This->glRect.left = 0; - This->glRect.top = 0; - This->glRect.right = 0; - This->glRect.bottom = 0; - } else { - /* Check this after the oversize check - do not make an oversized surface a texture_rectangle one. - Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE + /* We should never use this surface in combination with OpenGL! */ + TRACE("(%p) Creating an oversized surface: %ux%u\n", This, This->pow2Width, This->pow2Height); + } + else + { + /* Don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE doesn't work in combination with ARB_TEXTURE_RECTANGLE. */ @@ -4294,19 +4048,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { This->pow2Height = This->currentDesc.Height; This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD); } - - /* No oversize, gl rect is the full texture size */ - This->Flags &= ~SFLAG_OVERSIZE; - This->glRect.left = 0; - This->glRect.top = 0; - This->glRect.right = This->pow2Width; - This->glRect.bottom = This->pow2Height; } if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { switch(wined3d_settings.offscreen_rendering_mode) { case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break; - case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break; case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break; } } @@ -4316,104 +4062,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { return WINED3D_OK; } -struct depth_blt_info -{ - GLenum binding; - GLenum bind_target; - enum tex_types tex_type; - GLfloat coords[4][3]; -}; - -static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, struct depth_blt_info *info) -{ - GLfloat (*coords)[3] = info->coords; - - switch (target) - { - default: - FIXME("Unsupported texture target %#x\n", target); - /* Fall back to GL_TEXTURE_2D */ - case GL_TEXTURE_2D: - info->binding = GL_TEXTURE_BINDING_2D; - info->bind_target = GL_TEXTURE_2D; - info->tex_type = tex_2d; - coords[0][0] = 0.0f; coords[0][1] = 1.0f; coords[0][2] = 0.0f; - coords[1][0] = 1.0f; coords[1][1] = 1.0f; coords[1][2] = 0.0f; - coords[2][0] = 0.0f; coords[2][1] = 0.0f; coords[2][2] = 0.0f; - coords[3][0] = 1.0f; coords[3][1] = 0.0f; coords[3][2] = 0.0f; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB; - info->bind_target = GL_TEXTURE_RECTANGLE_ARB; - info->tex_type = tex_rect; - coords[0][0] = 0.0f; coords[0][1] = h; coords[0][2] = 0.0f; - coords[1][0] = w; coords[1][1] = h; coords[1][2] = 0.0f; - coords[2][0] = 0.0f; coords[2][1] = 0.0f; coords[2][2] = 0.0f; - coords[3][0] = w; coords[3][1] = 0.0f; coords[3][2] = 0.0f; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = 1.0f; coords[0][1] = -1.0f; coords[0][2] = 1.0f; - coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f; - coords[2][0] = 1.0f; coords[2][1] = 1.0f; coords[2][2] = 1.0f; - coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f; - coords[1][0] = -1.0f; coords[1][1] = -1.0f; coords[1][2] = 1.0f; - coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f; - coords[3][0] = -1.0f; coords[3][1] = 1.0f; coords[3][2] = 1.0f; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = 1.0f; coords[0][2] = 1.0f; - coords[1][0] = 1.0f; coords[1][1] = 1.0f; coords[1][2] = 1.0f; - coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f; - coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f; - coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f; - coords[2][0] = -1.0f; coords[2][1] = -1.0f; coords[2][2] = 1.0f; - coords[3][0] = 1.0f; coords[3][1] = -1.0f; coords[3][2] = 1.0f; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = -1.0f; coords[0][1] = -1.0f; coords[0][2] = 1.0f; - coords[1][0] = 1.0f; coords[1][1] = -1.0f; coords[1][2] = 1.0f; - coords[2][0] = -1.0f; coords[2][1] = 1.0f; coords[2][2] = 1.0f; - coords[3][0] = 1.0f; coords[3][1] = 1.0f; coords[3][2] = 1.0f; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB; - info->bind_target = GL_TEXTURE_CUBE_MAP_ARB; - info->tex_type = tex_cube; - coords[0][0] = 1.0f; coords[0][1] = -1.0f; coords[0][2] = -1.0f; - coords[1][0] = -1.0f; coords[1][1] = -1.0f; coords[1][2] = -1.0f; - coords[2][0] = 1.0f; coords[2][1] = 1.0f; coords[2][2] = -1.0f; - coords[3][0] = -1.0f; coords[3][1] = 1.0f; coords[3][2] = -1.0f; - } -} - /* GL locking is done by the caller */ -static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target) +static void surface_depth_blt(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info, + GLuint texture, GLsizei w, GLsizei h, GLenum target) { IWineD3DDeviceImpl *device = This->resource.device; - struct depth_blt_info info; + GLint compare_mode = GL_NONE; + struct blt_info info; GLint old_binding = 0; glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT); @@ -4429,12 +4084,18 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glViewport(0, 0, w, h); - surface_get_depth_blt_info(target, w, h, &info); + surface_get_blt_info(target, NULL, w, h, &info); GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB)); glGetIntegerv(info.binding, &old_binding); glBindTexture(info.bind_target, texture); + if (gl_info->supported[ARB_SHADOW]) + { + glGetTexParameteriv(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, &compare_mode); + if (compare_mode != GL_NONE) glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } - device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, info.tex_type); + device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, + info.tex_type, &This->ds_current_size); glBegin(GL_TRIANGLE_STRIP); glTexCoord3fv(info.coords[0]); @@ -4447,6 +4108,7 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei glVertex2f(1.0f, 1.0f); glEnd(); + if (compare_mode != GL_NONE) glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, compare_mode); glBindTexture(info.bind_target, old_binding); glPopAttrib(); @@ -4454,139 +4116,156 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei device->shader_backend->shader_deselect_depth_blt((IWineD3DDevice *)device); } -void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; +void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, + DWORD location, UINT w, UINT h) +{ + TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); - TRACE("(%p) New location %#x\n", This, location); + if (location & ~SFLAG_DS_LOCATIONS) + FIXME("Invalid location (%#x) specified.\n", location); - if (location & ~SFLAG_DS_LOCATIONS) { - FIXME("(%p) Invalid location (%#x) specified\n", This, location); - } - - This->Flags &= ~SFLAG_DS_LOCATIONS; - This->Flags |= location; + surface->ds_current_size.cx = w; + surface->ds_current_size.cy = h; + surface->Flags &= ~SFLAG_DS_LOCATIONS; + surface->Flags |= location; } /* Context activation is done by the caller. */ -void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location) +void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_context *context, DWORD location) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - IWineD3DDeviceImpl *device = This->resource.device; + IWineD3DDeviceImpl *device = surface->resource.device; const struct wined3d_gl_info *gl_info = context->gl_info; - TRACE("(%p) New location %#x\n", This, location); + TRACE("surface %p, new location %#x.\n", surface, location); /* TODO: Make this work for modes other than FBO */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; - if (This->Flags & location) { - TRACE("(%p) Location (%#x) is already up to date\n", This, location); + if (!(surface->Flags & location)) + { + surface->ds_current_size.cx = 0; + surface->ds_current_size.cy = 0; + } + + if (surface->ds_current_size.cx == surface->currentDesc.Width + && surface->ds_current_size.cy == surface->currentDesc.Height) + { + TRACE("Location (%#x) is already up to date.\n", location); return; } - if (This->current_renderbuffer) { - FIXME("(%p) Not supported with fixed up depth stencil\n", This); + if (surface->current_renderbuffer) + { + FIXME("Not supported with fixed up depth stencil.\n"); return; } - if (location == SFLAG_DS_OFFSCREEN) { - if (This->Flags & SFLAG_DS_ONSCREEN) { - GLint old_binding = 0; - GLenum bind_target; - - TRACE("(%p) Copying onscreen depth buffer to depth texture\n", This); - - ENTER_GL(); - - if (!device->depth_blt_texture) { - glGenTextures(1, &device->depth_blt_texture); - } - - /* Note that we use depth_blt here as well, rather than glCopyTexImage2D - * directly on the FBO texture. That's because we need to flip. */ - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) - { - glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); - bind_target = GL_TEXTURE_RECTANGLE_ARB; - } else { - glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); - bind_target = GL_TEXTURE_2D; - } - glBindTexture(bind_target, device->depth_blt_texture); - glCopyTexImage2D(bind_target, This->texture_level, This->resource.format_desc->glInternal, - 0, 0, This->currentDesc.Width, This->currentDesc.Height, 0); - glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); - glBindTexture(bind_target, old_binding); - - /* Setup the destination */ - if (!device->depth_blt_rb) { - gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb); - checkGLcall("glGenRenderbuffersEXT"); - } - if (device->depth_blt_rb_w != This->currentDesc.Width - || device->depth_blt_rb_h != This->currentDesc.Height) { - gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb); - checkGLcall("glBindRenderbufferEXT"); - gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, - This->currentDesc.Width, This->currentDesc.Height); - checkGLcall("glRenderbufferStorageEXT"); - device->depth_blt_rb_w = This->currentDesc.Width; - device->depth_blt_rb_h = This->currentDesc.Height; - } - - context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb); - checkGLcall("glFramebufferRenderbufferEXT"); - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, iface, FALSE); - - /* Do the actual blit */ - surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target); - checkGLcall("depth_blt"); - - if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); - else context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - - LEAVE_GL(); - - wglFlush(); /* Flush to ensure ordering across contexts. */ - } - else - { - FIXME("No up to date depth stencil location\n"); - } - } else if (location == SFLAG_DS_ONSCREEN) { - if (This->Flags & SFLAG_DS_OFFSCREEN) { - TRACE("(%p) Copying depth texture to onscreen depth buffer\n", This); - - ENTER_GL(); - - context_bind_fbo(context, GL_FRAMEBUFFER, NULL); - surface_depth_blt(This, This->texture_name, This->currentDesc.Width, - This->currentDesc.Height, This->texture_target); - checkGLcall("depth_blt"); - - if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); - - LEAVE_GL(); - - wglFlush(); /* Flush to ensure ordering across contexts. */ - } - else - { - FIXME("No up to date depth stencil location\n"); - } - } else { - ERR("(%p) Invalid location (%#x) specified\n", This, location); + if (!(surface->Flags & SFLAG_LOCATIONS)) + { + FIXME("No up to date depth stencil location.\n"); + surface->Flags |= location; + return; } - This->Flags |= location; + if (location == SFLAG_DS_OFFSCREEN) + { + GLint old_binding = 0; + GLenum bind_target; + + TRACE("Copying onscreen depth buffer to depth texture.\n"); + + ENTER_GL(); + + if (!device->depth_blt_texture) + { + glGenTextures(1, &device->depth_blt_texture); + } + + /* Note that we use depth_blt here as well, rather than glCopyTexImage2D + * directly on the FBO texture. That's because we need to flip. */ + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB) + { + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); + bind_target = GL_TEXTURE_RECTANGLE_ARB; + } + else + { + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); + bind_target = GL_TEXTURE_2D; + } + glBindTexture(bind_target, device->depth_blt_texture); + glCopyTexImage2D(bind_target, surface->texture_level, surface->resource.format_desc->glInternal, + 0, 0, surface->currentDesc.Width, surface->currentDesc.Height, 0); + glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); + glBindTexture(bind_target, old_binding); + + /* Setup the destination */ + if (!device->depth_blt_rb) + { + gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb); + checkGLcall("glGenRenderbuffersEXT"); + } + if (device->depth_blt_rb_w != surface->currentDesc.Width + || device->depth_blt_rb_h != surface->currentDesc.Height) + { + gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb); + checkGLcall("glBindRenderbufferEXT"); + gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, + surface->currentDesc.Width, surface->currentDesc.Height); + checkGLcall("glRenderbufferStorageEXT"); + device->depth_blt_rb_w = surface->currentDesc.Width; + device->depth_blt_rb_h = surface->currentDesc.Height; + } + + context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); + gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb); + checkGLcall("glFramebufferRenderbufferEXT"); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, surface, FALSE); + + /* Do the actual blit */ + surface_depth_blt(surface, gl_info, device->depth_blt_texture, + surface->currentDesc.Width, surface->currentDesc.Height, bind_target); + checkGLcall("depth_blt"); + + if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); + else context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + + LEAVE_GL(); + + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ + } + else if (location == SFLAG_DS_ONSCREEN) + { + TRACE("Copying depth texture to onscreen depth buffer.\n"); + + ENTER_GL(); + + context_bind_fbo(context, GL_FRAMEBUFFER, NULL); + surface_depth_blt(surface, gl_info, surface->texture_name, + surface->currentDesc.Width, surface->currentDesc.Height, surface->texture_target); + checkGLcall("depth_blt"); + + if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id); + + LEAVE_GL(); + + if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */ + } + else + { + ERR("Invalid location (%#x) specified.\n", location); + } + + surface->Flags |= location; + surface->ds_current_size.cx = surface->currentDesc.Width; + surface->ds_current_size.cy = surface->currentDesc.Height; } static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) { @@ -4597,8 +4276,9 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW TRACE("(%p)->(%s, %s)\n", iface, debug_surflocation(flag), persistent ? "TRUE" : "FALSE"); - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (surface_is_offscreen(iface)) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if (surface_is_offscreen(This)) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); @@ -4643,185 +4323,44 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW } } -struct coords { - GLfloat x, y, z; -}; - -struct float_rect -{ - float l; - float t; - float r; - float b; -}; - -static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f) -{ - f->l = ((r->left * 2.0f) / w) - 1.0f; - f->t = ((r->top * 2.0f) / h) - 1.0f; - f->r = ((r->right * 2.0f) / w) - 1.0f; - f->b = ((r->bottom * 2.0f) / h) - 1.0f; -} - static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) { IWineD3DDeviceImpl *device = This->resource.device; - IWineD3DBaseTextureImpl *texture; + IWineD3DSwapChainImpl *swapchain; struct wined3d_context *context; - struct coords coords[4]; - RECT rect; - GLenum bind_target; - struct float_rect f; + RECT src_rect, dst_rect; - if(rect_in) { - rect = *rect_in; - } else { - rect.left = 0; - rect.top = 0; - rect.right = This->currentDesc.Width; - rect.bottom = This->currentDesc.Height; - } - - switch (This->texture_target) - { - case GL_TEXTURE_2D: - bind_target = GL_TEXTURE_2D; - - coords[0].x = (float)rect.left / This->pow2Width; - coords[0].y = (float)rect.top / This->pow2Height; - coords[0].z = 0; - - coords[1].x = (float)rect.left / This->pow2Width; - coords[1].y = (float)rect.bottom / This->pow2Height; - coords[1].z = 0; - - coords[2].x = (float)rect.right / This->pow2Width; - coords[2].y = (float)rect.bottom / This->pow2Height; - coords[2].z = 0; - - coords[3].x = (float)rect.right / This->pow2Width; - coords[3].y = (float)rect.top / This->pow2Height; - coords[3].z = 0; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - bind_target = GL_TEXTURE_RECTANGLE_ARB; - coords[0].x = rect.left; coords[0].y = rect.top; coords[0].z = 0; - coords[1].x = rect.left; coords[1].y = rect.bottom; coords[1].z = 0; - coords[2].x = rect.right; coords[2].y = rect.bottom; coords[2].z = 0; - coords[3].x = rect.right; coords[3].y = rect.top; coords[3].z = 0; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = 1; coords[0].y = -f.t; coords[0].z = -f.l; - coords[1].x = 1; coords[1].y = -f.b; coords[1].z = -f.l; - coords[2].x = 1; coords[2].y = -f.b; coords[2].z = -f.r; - coords[3].x = 1; coords[3].y = -f.t; coords[3].z = -f.r; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = -1; coords[0].y = -f.t; coords[0].z = f.l; - coords[1].x = -1; coords[1].y = -f.b; coords[1].z = f.l; - coords[2].x = -1; coords[2].y = -f.b; coords[2].z = f.r; - coords[3].x = -1; coords[3].y = -f.t; coords[3].z = f.r; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = f.l; coords[0].y = 1; coords[0].z = f.t; - coords[1].x = f.l; coords[1].y = 1; coords[1].z = f.b; - coords[2].x = f.r; coords[2].y = 1; coords[2].z = f.b; - coords[3].x = f.r; coords[3].y = 1; coords[3].z = f.t; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = f.l; coords[0].y = -1; coords[0].z = -f.t; - coords[1].x = f.l; coords[1].y = -1; coords[1].z = -f.b; - coords[2].x = f.r; coords[2].y = -1; coords[2].z = -f.b; - coords[3].x = f.r; coords[3].y = -1; coords[3].z = -f.t; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1; - coords[1].x = f.l; coords[1].y = -f.b; coords[1].z = 1; - coords[2].x = f.r; coords[2].y = -f.b; coords[2].z = 1; - coords[3].x = f.r; coords[3].y = -f.t; coords[3].z = 1; - break; - - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - bind_target = GL_TEXTURE_CUBE_MAP_ARB; - cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f); - coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1; - coords[1].x = -f.l; coords[1].y = -f.b; coords[1].z = -1; - coords[2].x = -f.r; coords[2].y = -f.b; coords[2].z = -1; - coords[3].x = -f.r; coords[3].y = -f.t; coords[3].z = -1; - break; - - default: - ERR("Unexpected texture target %#x\n", This->texture_target); - return; - } - - context = context_acquire(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT); - - ENTER_GL(); - - glEnable(bind_target); - checkGLcall("glEnable(bind_target)"); - glBindTexture(bind_target, This->texture_name); - checkGLcall("glBindTexture(bind_target, This->texture_name)"); - glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); + surface_get_rect(This, rect_in, &src_rect); + context = context_acquire(device, This); + context_apply_blit_state(context, device); if (context->render_offscreen) { - LONG tmp = rect.top; - rect.top = rect.bottom; - rect.bottom = tmp; + dst_rect.left = src_rect.left; + dst_rect.right = src_rect.right; + dst_rect.top = src_rect.bottom; + dst_rect.bottom = src_rect.top; + } + else + { + dst_rect = src_rect; } - glBegin(GL_QUADS); - glTexCoord3fv(&coords[0].x); - glVertex2i(rect.left, rect.top); + if ((This->Flags & SFLAG_SWAPCHAIN) && This == ((IWineD3DSwapChainImpl *)This->container)->front_buffer) + surface_translate_frontbuffer_coords(This, context->win_handle, &dst_rect); - glTexCoord3fv(&coords[1].x); - glVertex2i(rect.left, rect.bottom); - - glTexCoord3fv(&coords[2].x); - glVertex2i(rect.right, rect.bottom); - - glTexCoord3fv(&coords[3].x); - glVertex2i(rect.right, rect.top); - glEnd(); - checkGLcall("glEnd"); - - glDisable(bind_target); - checkGLcall("glDisable(bind_target)"); + device->blitter->set_shader((IWineD3DDevice *) device, This); + ENTER_GL(); + draw_textured_quad(This, &src_rect, &dst_rect, WINED3DTEXF_POINT); LEAVE_GL(); - wglFlush(); /* Flush to ensure ordering across contexts. */ + device->blitter->set_shader((IWineD3DDevice *) device, This); - /* We changed the filtering settings on the texture. Inform the - * container about this to get the filters reset properly next draw. */ - if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)This, &IID_IWineD3DBaseTexture, (void **)&texture))) - { - texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; - texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; - texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; - IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture); - } + swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL; + if (wined3d_settings.strict_draw_ordering || (swapchain + && (This == swapchain->front_buffer || swapchain->num_contexts > 1))) + wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); } @@ -4851,16 +4390,32 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DDeviceImpl *device = This->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - GLenum format, internal, type; + struct wined3d_format_desc desc; CONVERT_TYPES convert; - int bpp; int width, pitch, outpitch; BYTE *mem; BOOL drawable_read_ok = TRUE; BOOL in_fbo = FALSE; - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (surface_is_offscreen(iface)) + if (This->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (flag == SFLAG_INTEXTURE) + { + struct wined3d_context *context = context_acquire(device, NULL); + surface_load_ds_location(This, context, SFLAG_DS_OFFSCREEN); + context_release(context); + return WINED3D_OK; + } + else + { + FIXME("Unimplemented location %#x for depth/stencil buffers.\n", flag); + return WINED3DERR_INVALIDCALL; + } + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if (surface_is_offscreen(This)) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. * Prefer SFLAG_INTEXTURE. */ @@ -4898,10 +4453,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D { struct wined3d_context *context = NULL; - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE)); - surface_download_data(This); + surface_download_data(This, gl_info); if (context) context_release(context); } @@ -4916,6 +4471,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D if(This->Flags & SFLAG_INTEXTURE) { surface_blt_to_drawable(This, rect); } else { + int byte_count; if((This->Flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX) { /* This needs a shader to convert the srgb data sampled from the GL texture into RGB * values, otherwise we get incorrect values in the target. For now go the slow way @@ -4924,7 +4480,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect); } - d3dfmt_get_conv(This, TRUE /* We need color keying */, FALSE /* We won't use textures */, &format, &internal, &type, &convert, &bpp, FALSE); + d3dfmt_get_conv(This, FALSE /* We need color keying */, FALSE /* We won't use textures */, &desc, &convert); /* The width is in 'length' not in bytes */ width = This->currentDesc.Width; @@ -4938,16 +4494,17 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D TRACE("Removing the pbo attached to surface %p\n", This); - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); - surface_remove_pbo(This); + if (!device->isInDraw) context = context_acquire(device, NULL); + surface_remove_pbo(This, gl_info); if (context) context_release(context); } if((convert != NO_CONVERSION) && This->resource.allocatedMemory) { int height = This->currentDesc.Height; + byte_count = desc.conv_byte_count; /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ - outpitch = width * bpp; + outpitch = width * byte_count; outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height); @@ -4961,9 +4518,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D } else { This->Flags &= ~SFLAG_CONVERTED; mem = This->resource.allocatedMemory; + byte_count = desc.byte_count; } - flush_to_framebuffer_drawpixels(This, format, type, bpp, mem); + flush_to_framebuffer_drawpixels(This, desc.glFormat, desc.glType, byte_count, mem); /* Don't delete PBO memory */ if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO)) @@ -4980,7 +4538,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D struct wined3d_context *context = NULL; d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, - &format, &internal, &type, &convert, &bpp, srgb); + &desc, &convert); if(srgb) { if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) { @@ -5002,9 +4560,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect); } - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); - surface_prepare_texture(This, srgb); + surface_prepare_texture(This, gl_info, srgb); surface_bind_and_dirtify(This, srgb); if(This->CKeyFlags & WINEDDSD_CKSRCBLT) { @@ -5019,16 +4577,32 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D /* Don't use PBOs for converted surfaces. During PBO conversion we look at SFLAG_CONVERTED * but it isn't set (yet) in all cases it is getting called. */ - if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) { + if(((convert != NO_CONVERSION) || desc.convert) && (This->Flags & SFLAG_PBO)) { TRACE("Removing the pbo attached to surface %p\n", This); - surface_remove_pbo(This); + surface_remove_pbo(This, gl_info); } - if((convert != NO_CONVERSION) && This->resource.allocatedMemory) { + if(desc.convert) { + /* This code is entered for texture formats which need a fixup. */ int height = This->currentDesc.Height; /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ - outpitch = width * bpp; + outpitch = width * desc.conv_byte_count; + outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); + + mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height); + if(!mem) { + ERR("Out of memory %d, %d!\n", outpitch, height); + if (context) context_release(context); + return WINED3DERR_OUTOFVIDEOMEMORY; + } + desc.convert(This->resource.allocatedMemory, mem, pitch, width, height); + } else if((convert != NO_CONVERSION) && This->resource.allocatedMemory) { + /* This code is only entered for color keying fixups */ + int height = This->currentDesc.Height; + + /* Stick to the alignment for the converted surface too, makes it easier to load the surface */ + outpitch = width * desc.conv_byte_count; outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height); @@ -5038,12 +4612,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D return WINED3DERR_OUTOFVIDEOMEMORY; } d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This); - } - else if (This->resource.format_desc->format == WINED3DFMT_P8_UINT - && (gl_info->supported[EXT_PALETTED_TEXTURE] || device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup))) - { - d3dfmt_p8_upload_palette(iface, convert); - mem = This->resource.allocatedMemory; } else { mem = This->resource.allocatedMemory; } @@ -5053,19 +4621,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D glPixelStorei(GL_UNPACK_ROW_LENGTH, width); LEAVE_GL(); - if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) { - TRACE("non power of two support\n"); - if (mem || (This->Flags & SFLAG_PBO)) { - surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem); - } - } else { - /* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory - * changed. So also keep track of memory changes. In this case the texture has to be reallocated - */ - if (mem || (This->Flags & SFLAG_PBO)) { - surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem); - } - } + if (mem || (This->Flags & SFLAG_PBO)) + surface_upload_data(This, gl_info, &desc, srgb, mem); /* Restore the default pitch */ ENTER_GL(); @@ -5107,7 +4664,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, I } else if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { switch(wined3d_settings.offscreen_rendering_mode) { case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break; - case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break; case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break; } } @@ -5141,16 +4697,15 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) { return hr; } -BOOL surface_is_offscreen(IWineD3DSurface *iface) +BOOL surface_is_offscreen(IWineD3DSurfaceImpl *surface) { - IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) This->container; + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container; /* Not on a swapchain - must be offscreen */ - if (!(This->Flags & SFLAG_SWAPCHAIN)) return TRUE; + if (!(surface->Flags & SFLAG_SWAPCHAIN)) return TRUE; /* The front buffer is always onscreen */ - if(iface == swapchain->frontBuffer) return FALSE; + if (surface == swapchain->front_buffer) return FALSE; /* If the swapchain is rendered to an FBO, the backbuffer is * offscreen, otherwise onscreen */ @@ -5212,20 +4767,42 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_GetImplType, IWineD3DSurfaceImpl_DrawOverlay }; -#undef GLINFO_LOCATION -#define GLINFO_LOCATION device->adapter->gl_info static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; } /* Context activation is done by the caller. */ static void ffp_blit_free(IWineD3DDevice *iface) { } +/* This function is used in case of 8bit paletted textures using GL_EXT_paletted_texture */ /* Context activation is done by the caller. */ -static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, - GLenum textype, UINT width, UINT height) +static void ffp_blit_p8_upload_palette(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info) { + BYTE table[256][4]; + BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) ? TRUE : FALSE; + + d3dfmt_p8_init_palette(surface, table, colorkey_active); + + TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n"); ENTER_GL(); - glEnable(textype); - checkGLcall("glEnable(textype)"); + GL_EXTCALL(glColorTableEXT(surface->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table)); + LEAVE_GL(); +} + +/* Context activation is done by the caller. */ +static HRESULT ffp_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface) +{ + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + enum complex_fixup fixup = get_complex_fixup(surface->resource.format_desc->color_fixup); + + /* When EXT_PALETTED_TEXTURE is around, palette conversion is done by the GPU + * else the surface is converted in software at upload time in LoadLocation. + */ + if(fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE]) + ffp_blit_p8_upload_palette(surface, gl_info); + + ENTER_GL(); + glEnable(surface->texture_target); + checkGLcall("glEnable(surface->texture_target)"); LEAVE_GL(); return WINED3D_OK; } @@ -5252,16 +4829,52 @@ static void ffp_blit_unset(IWineD3DDevice *iface) LEAVE_GL(); } -static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup) +static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) { + enum complex_fixup src_fixup; + + if (blit_op == BLIT_OP_COLOR_FILL) + { + if (!(dst_usage & WINED3DUSAGE_RENDERTARGET)) + { + TRACE("Color fill not supported\n"); + return FALSE; + } + + return TRUE; + } + + src_fixup = get_complex_fixup(src_format_desc->color_fixup); if (TRACE_ON(d3d_surface) && TRACE_ON(d3d)) { TRACE("Checking support for fixup:\n"); - dump_color_fixup_desc(fixup); + dump_color_fixup_desc(src_format_desc->color_fixup); + } + + if (blit_op != BLIT_OP_BLIT) + { + TRACE("Unsupported blit_op=%d\n", blit_op); + return FALSE; + } + + if (!is_identity_fixup(dst_format_desc->color_fixup)) + { + TRACE("Destination fixups are not supported\n"); + return FALSE; + } + + if (src_fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE]) + { + TRACE("P8 fixup supported\n"); + return TRUE; } /* We only support identity conversions. */ - if (is_identity_fixup(fixup)) + if (is_identity_fixup(src_format_desc->color_fixup)) { TRACE("[OK]\n"); return TRUE; @@ -5271,10 +4884,105 @@ static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup) return FALSE; } +static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +{ + return IWineD3DDeviceImpl_ClearSurface(device, dst_surface, 1 /* Number of rectangles */, + (const WINED3DRECT*)dst_rect, WINED3DCLEAR_TARGET, fill_color, 0.0f /* Z */, 0 /* Stencil */); +} + const struct blit_shader ffp_blit = { ffp_blit_alloc, ffp_blit_free, ffp_blit_set, ffp_blit_unset, - ffp_blit_color_fixup_supported + ffp_blit_supported, + ffp_blit_color_fill }; + +static HRESULT cpu_blit_alloc(IWineD3DDevice *iface) +{ + return WINED3D_OK; +} + +/* Context activation is done by the caller. */ +static void cpu_blit_free(IWineD3DDevice *iface) +{ +} + +/* Context activation is done by the caller. */ +static HRESULT cpu_blit_set(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface) +{ + return WINED3D_OK; +} + +/* Context activation is done by the caller. */ +static void cpu_blit_unset(IWineD3DDevice *iface) +{ +} + +static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) +{ + if (blit_op == BLIT_OP_COLOR_FILL) + { + return TRUE; + } + + return FALSE; +} + +static HRESULT cpu_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +{ + WINEDDBLTFX BltFx; + memset(&BltFx, 0, sizeof(BltFx)); + BltFx.dwSize = sizeof(BltFx); + BltFx.u5.dwFillColor = color_convert_argb_to_fmt(fill_color, dst_surface->resource.format_desc->format); + return IWineD3DBaseSurfaceImpl_Blt((IWineD3DSurface*)dst_surface, dst_rect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT); +} + +const struct blit_shader cpu_blit = { + cpu_blit_alloc, + cpu_blit_free, + cpu_blit_set, + cpu_blit_unset, + cpu_blit_supported, + cpu_blit_color_fill +}; + +static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, + const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, + const struct wined3d_format_desc *dst_format_desc) +{ + if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer) + return FALSE; + + /* We only support blitting. Things like color keying / color fill should + * be handled by other blitters. + */ + if (blit_op != BLIT_OP_BLIT) + return FALSE; + + /* Source and/or destination need to be on the GL side */ + if (src_pool == WINED3DPOOL_SYSTEMMEM || dst_pool == WINED3DPOOL_SYSTEMMEM) + return FALSE; + + if(!((src_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (src_usage & WINED3DUSAGE_RENDERTARGET)) + && ((dst_format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET))) + return FALSE; + + if (!is_identity_fixup(src_format_desc->color_fixup) || + !is_identity_fixup(dst_format_desc->color_fixup)) + return FALSE; + + if (!(src_format_desc->format == dst_format_desc->format + || (is_identity_fixup(src_format_desc->color_fixup) + && is_identity_fixup(dst_format_desc->color_fixup)))) + return FALSE; + + return TRUE; +} diff --git a/dll/directx/wine/wined3d/surface_base.c b/dll/directx/wine/wined3d/surface_base.c index 33e3d3ed885..2b6cdb41f22 100644 --- a/dll/directx/wine/wined3d/surface_base.c +++ b/dll/directx/wine/wined3d/surface_base.c @@ -83,9 +83,6 @@ static inline unsigned short float_32_to_16(const float *in) return ret; } - -/* Do NOT define GLINFO_LOCATION in this file. THIS CODE MUST NOT USE IT */ - /* ******************************************* IWineD3DSurface IUnknown parts follow ******************************************* */ @@ -326,7 +323,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; DWORD ret; TRACE("(%p)\n", This); @@ -502,7 +499,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWin HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, &This->resource.device->adapter->gl_info); if (This->resource.format_desc->format != WINED3DFMT_UNKNOWN) @@ -527,7 +524,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D HRESULT IWineD3DBaseSurfaceImpl_CreateDIBSection(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; int extraline = 0; SYSTEM_INFO sysInfo; BITMAPINFO* b_info; @@ -742,6 +739,55 @@ static void convert_a8r8g8b8_x8r8g8b8(const BYTE *src, BYTE *dst, } } +static inline BYTE cliptobyte(int x) +{ + return (BYTE) ((x < 0) ? 0 : ((x > 255) ? 255 : x)); +} + +static void convert_yuy2_x8r8g8b8(const BYTE *src, BYTE *dst, + DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h) +{ + unsigned int x, y; + int c2, d, e, r2 = 0, g2 = 0, b2 = 0; + + TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out); + + for (y = 0; y < h; ++y) + { + const BYTE *src_line = src + y * pitch_in; + DWORD *dst_line = (DWORD *)(dst + y * pitch_out); + for (x = 0; x < w; ++x) + { + /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV: + * C = Y - 16; D = U - 128; E = V - 128; + * R = cliptobyte((298 * C + 409 * E + 128) >> 8); + * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8); + * B = cliptobyte((298 * C + 516 * D + 128) >> 8); + * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V . + * U and V are shared between the pixels. + */ + if (!(x & 1)) /* for every even pixel, read new U and V */ + { + d = (int) src_line[1] - 128; + e = (int) src_line[3] - 128; + r2 = 409 * e + 128; + g2 = - 100 * d - 208 * e + 128; + b2 = 516 * d + 128; + } + c2 = 298 * ((int) src_line[0] - 16); + dst_line[x] = 0xff000000 + | cliptobyte((c2 + r2) >> 8) << 16 /* red */ + | cliptobyte((c2 + g2) >> 8) << 8 /* green */ + | cliptobyte((c2 + b2) >> 8); /* blue */ + /* Scale RGB values to 0..255 range, + * then clip them if still not in range (may be negative), + * then shift them within DWORD if necessary. + */ + src_line += 2; + } + } +} + struct d3dfmt_convertor_desc { WINED3DFORMAT from, to; void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h); @@ -752,6 +798,7 @@ static const struct d3dfmt_convertor_desc convertors[] = {WINED3DFMT_R32_FLOAT, WINED3DFMT_R16_FLOAT, convert_r32_float_r16_float}, {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_r5g6b5_x8r8g8b8}, {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_a8r8g8b8_x8r8g8b8}, + {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8}, }; static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to) @@ -892,7 +939,7 @@ static HRESULT /***************************************************************************** * IWineD3DSurface::Blt, SW emulation version * - * Performs blits to a surface, eigher from a source of source-less blts + * Performs a blit to a surface, with or without a source surface. * This is the main functionality of DirectDraw * * Params: @@ -909,7 +956,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D HRESULT ret = WINED3D_OK; WINED3DLOCKED_RECT dlock, slock; int bpp, srcheight, srcwidth, dstheight, dstwidth, width; - const struct GlPixelFormatDesc *sEntry, *dEntry; + const struct wined3d_format_desc *sEntry, *dEntry; int x, y; const BYTE *sbuf; BYTE *dbuf; @@ -943,144 +990,145 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D FIXME("Filters not supported in software blit\n"); } - /* First check for the validity of source / destination rectangles. This was - * verified using a test application + by MSDN. - */ - if ((Src != NULL) && (SrcRect != NULL) && - ((SrcRect->bottom > Src->currentDesc.Height)||(SrcRect->bottom < 0) || - (SrcRect->top > Src->currentDesc.Height)||(SrcRect->top < 0) || - (SrcRect->left > Src->currentDesc.Width) ||(SrcRect->left < 0) || - (SrcRect->right > Src->currentDesc.Width) ||(SrcRect->right < 0) || - (SrcRect->right < SrcRect->left) ||(SrcRect->bottom < SrcRect->top))) - { - WARN("Application gave us bad source rectangle for Blt.\n"); - return WINEDDERR_INVALIDRECT; - } - /* For the Destination rect, it can be out of bounds on the condition that a clipper - * is set for the given surface. - */ - if ((/*This->clipper == NULL*/ TRUE) && (DestRect) && - ((DestRect->bottom > This->currentDesc.Height)||(DestRect->bottom < 0) || - (DestRect->top > This->currentDesc.Height)||(DestRect->top < 0) || - (DestRect->left > This->currentDesc.Width) ||(DestRect->left < 0) || - (DestRect->right > This->currentDesc.Width) ||(DestRect->right < 0) || - (DestRect->right < DestRect->left) ||(DestRect->bottom < DestRect->top))) - { - WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n"); - return WINEDDERR_INVALIDRECT; - } + /* First check for the validity of source / destination rectangles. + * This was verified using a test application + by MSDN. */ - /* Now handle negative values in the rectangles. Warning: only supported for now - in the 'simple' cases (ie not in any stretching / rotation cases). - - First, the case where nothing is to be done. - */ - if ((DestRect && ((DestRect->bottom <= 0) || (DestRect->right <= 0) || - (DestRect->top >= (int) This->currentDesc.Height) || - (DestRect->left >= (int) This->currentDesc.Width))) || - ((Src != NULL) && (SrcRect != NULL) && - ((SrcRect->bottom <= 0) || (SrcRect->right <= 0) || - (SrcRect->top >= (int) Src->currentDesc.Height) || - (SrcRect->left >= (int) Src->currentDesc.Width)) )) + if (SrcRect) { - TRACE("Nothing to be done !\n"); - return WINED3D_OK; + if (Src) + { + if (SrcRect->right < SrcRect->left || SrcRect->bottom < SrcRect->top + || SrcRect->left > Src->currentDesc.Width || SrcRect->left < 0 + || SrcRect->top > Src->currentDesc.Height || SrcRect->top < 0 + || SrcRect->right > Src->currentDesc.Width || SrcRect->right < 0 + || SrcRect->bottom > Src->currentDesc.Height || SrcRect->bottom < 0) + { + WARN("Application gave us bad source rectangle for Blt.\n"); + return WINEDDERR_INVALIDRECT; + } + + if (!SrcRect->right || !SrcRect->bottom + || SrcRect->left == (int)Src->currentDesc.Width + || SrcRect->top == (int)Src->currentDesc.Height) + { + TRACE("Nothing to be done.\n"); + return WINED3D_OK; + } + } + + xsrc = *SrcRect; + } + else if (Src) + { + xsrc.left = 0; + xsrc.top = 0; + xsrc.right = Src->currentDesc.Width; + xsrc.bottom = Src->currentDesc.Height; + } + else + { + memset(&xsrc, 0, sizeof(xsrc)); } if (DestRect) { - xdst = *DestRect; - } - else - { - xdst.top = 0; - xdst.bottom = This->currentDesc.Height; - xdst.left = 0; - xdst.right = This->currentDesc.Width; - } - - if (SrcRect) - { - xsrc = *SrcRect; - } - else - { - if (Src) + /* For the Destination rect, it can be out of bounds on the condition + * that a clipper is set for the given surface. */ + if (!This->clipper && (DestRect->right < DestRect->left || DestRect->bottom < DestRect->top + || DestRect->left > This->currentDesc.Width || DestRect->left < 0 + || DestRect->top > This->currentDesc.Height || DestRect->top < 0 + || DestRect->right > This->currentDesc.Width || DestRect->right < 0 + || DestRect->bottom > This->currentDesc.Height || DestRect->bottom < 0)) { - xsrc.top = 0; - xsrc.bottom = Src->currentDesc.Height; - xsrc.left = 0; - xsrc.right = Src->currentDesc.Width; + WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n"); + return WINEDDERR_INVALIDRECT; + } + + if (DestRect->right <= 0 || DestRect->bottom <= 0 + || DestRect->left >= (int)This->currentDesc.Width + || DestRect->top >= (int)This->currentDesc.Height) + { + TRACE("Nothing to be done.\n"); + return WINED3D_OK; + } + + if (!Src) + { + RECT full_rect; + + full_rect.left = 0; + full_rect.top = 0; + full_rect.right = This->currentDesc.Width; + full_rect.bottom = This->currentDesc.Height; + IntersectRect(&xdst, &full_rect, DestRect); } else { - memset(&xsrc,0,sizeof(xsrc)); + BOOL clip_horiz, clip_vert; + + xdst = *DestRect; + clip_horiz = xdst.left < 0 || xdst.right > (int)This->currentDesc.Width; + clip_vert = xdst.top < 0 || xdst.bottom > (int)This->currentDesc.Height; + + if (clip_vert || clip_horiz) + { + /* Now check if this is a special case or not... */ + if ((Flags & WINEDDBLT_DDFX) + || (clip_horiz && xdst.right - xdst.left != xsrc.right - xsrc.left) + || (clip_vert && xdst.bottom - xdst.top != xsrc.bottom - xsrc.top)) + { + WARN("Out of screen rectangle in special case. Not handled right now.\n"); + return WINED3D_OK; + } + + if (clip_horiz) + { + if (xdst.left < 0) + { + xsrc.left -= xdst.left; + xdst.left = 0; + } + if (xdst.right > This->currentDesc.Width) + { + xsrc.right -= (xdst.right - (int)This->currentDesc.Width); + xdst.right = (int)This->currentDesc.Width; + } + } + + if (clip_vert) + { + if (xdst.top < 0) + { + xsrc.top -= xdst.top; + xdst.top = 0; + } + if (xdst.bottom > This->currentDesc.Height) + { + xsrc.bottom -= (xdst.bottom - (int)This->currentDesc.Height); + xdst.bottom = (int)This->currentDesc.Height; + } + } + + /* And check if after clipping something is still to be done... */ + if ((xdst.right <= 0) || (xdst.bottom <= 0) + || (xdst.left >= (int)This->currentDesc.Width) + || (xdst.top >= (int)This->currentDesc.Height) + || (xsrc.right <= 0) || (xsrc.bottom <= 0) + || (xsrc.left >= (int) Src->currentDesc.Width) + || (xsrc.top >= (int)Src->currentDesc.Height)) + { + TRACE("Nothing to be done after clipping.\n"); + return WINED3D_OK; + } + } } } - - /* The easy case : the source-less blits.... */ - if (Src == NULL && DestRect) + else { - RECT full_rect; - RECT temp_rect; /* No idea if intersect rect can be the same as one of the source rect */ - - full_rect.left = 0; - full_rect.top = 0; - full_rect.right = This->currentDesc.Width; - full_rect.bottom = This->currentDesc.Height; - IntersectRect(&temp_rect, &full_rect, DestRect); - xdst = temp_rect; - } - else if (DestRect) - { - /* Only handle clipping on the destination rectangle */ - int clip_horiz = (DestRect->left < 0) || (DestRect->right > (int) This->currentDesc.Width ); - int clip_vert = (DestRect->top < 0) || (DestRect->bottom > (int) This->currentDesc.Height); - if (clip_vert || clip_horiz) - { - /* Now check if this is a special case or not... */ - if ((((DestRect->bottom - DestRect->top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) || - (((DestRect->right - DestRect->left) != (xsrc.right - xsrc.left)) && clip_horiz) || - (Flags & WINEDDBLT_DDFX)) - { - WARN("Out of screen rectangle in special case. Not handled right now.\n"); - return WINED3D_OK; - } - - if (clip_horiz) - { - if (DestRect->left < 0) { xsrc.left -= DestRect->left; xdst.left = 0; } - if (DestRect->right > This->currentDesc.Width) - { - xsrc.right -= (DestRect->right - (int) This->currentDesc.Width); - xdst.right = (int) This->currentDesc.Width; - } - } - if (clip_vert) - { - if (DestRect->top < 0) - { - xsrc.top -= DestRect->top; - xdst.top = 0; - } - if (DestRect->bottom > This->currentDesc.Height) - { - xsrc.bottom -= (DestRect->bottom - (int) This->currentDesc.Height); - xdst.bottom = (int) This->currentDesc.Height; - } - } - /* And check if after clipping something is still to be done... */ - if ((xdst.bottom <= 0) || (xdst.right <= 0) || - (xdst.top >= (int) This->currentDesc.Height) || - (xdst.left >= (int) This->currentDesc.Width) || - (xsrc.bottom <= 0) || (xsrc.right <= 0) || - (xsrc.top >= (int) Src->currentDesc.Height) || - (xsrc.left >= (int) Src->currentDesc.Width)) - { - TRACE("Nothing to be done after clipping !\n"); - return WINED3D_OK; - } - } + xdst.left = 0; + xdst.top = 0; + xdst.right = This->currentDesc.Width; + xdst.bottom = This->currentDesc.Height; } if (Src == This) @@ -1552,7 +1600,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dst RECT lock_src, lock_dst, lock_union; const BYTE *sbuf; BYTE *dbuf; - const struct GlPixelFormatDesc *sEntry, *dEntry; + const struct wined3d_format_desc *sEntry, *dEntry; if (TRACE_ON(d3d_surface)) { @@ -1833,7 +1881,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL } else { - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom); diff --git a/dll/directx/wine/wined3d/surface_gdi.c b/dll/directx/wine/wined3d/surface_gdi.c index 3f09dc3c130..580c88a9080 100644 --- a/dll/directx/wine/wined3d/surface_gdi.c +++ b/dll/directx/wine/wined3d/surface_gdi.c @@ -200,7 +200,7 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface) /* Tell the swapchain to update the screen */ if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { - if(iface == swapchain->frontBuffer) + if (This == swapchain->front_buffer) { x11_copy_to_screen(swapchain, &This->lockedRect); } @@ -240,7 +240,8 @@ IWineGDISurfaceImpl_Flip(IWineD3DSurface *iface, return WINEDDERR_NOTFLIPPABLE; } - hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0); + hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *)swapchain, + NULL, NULL, swapchain->win_handle, NULL, 0); IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); return hr; } @@ -296,9 +297,9 @@ const char* filename) FILE* f = NULL; UINT y = 0, x = 0; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + const struct wined3d_format_desc *format_desc = This->resource.format_desc; static char *output = NULL; static UINT size = 0; - const struct GlPixelFormatDesc *format_desc = This->resource.format_desc; if (This->pow2Width > size) { output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3); @@ -340,14 +341,13 @@ const char* filename) fwrite(output, 3 * This->pow2Width, 1, f); } } else { - int red_shift, green_shift, blue_shift, pix_width, alpha_shift; + int red_shift, green_shift, blue_shift, pix_width; pix_width = format_desc->byte_count; red_shift = get_shift(format_desc->red_mask); green_shift = get_shift(format_desc->green_mask); blue_shift = get_shift(format_desc->blue_mask); - alpha_shift = get_shift(format_desc->alpha_mask); for (y = 0; y < This->pow2Height; y++) { const unsigned char *src = This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface)); @@ -366,8 +366,8 @@ const char* filename) output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift; comp = color & format_desc->green_mask; output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift; - comp = color & format_desc->alpha_mask; - output[3 * x + 2] = alpha_shift > 0 ? comp >> alpha_shift : comp << -alpha_shift; + comp = color & format_desc->blue_mask; + output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift; } fwrite(output, 3 * This->pow2Width, 1, f); } @@ -430,7 +430,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD IWineD3DSurfaceImpl *dds_primary; IWineD3DSwapChainImpl *swapchain; swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0]; - dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer; + dds_primary = swapchain->front_buffer; if (dds_primary && dds_primary->palette) pal = dds_primary->palette->palents; } @@ -500,7 +500,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) /* Tell the swapchain to update the screen */ if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { - if(iface == swapchain->frontBuffer) + if (This == swapchain->front_buffer) { x11_copy_to_screen(swapchain, NULL); } diff --git a/dll/directx/wine/wined3d/swapchain.c b/dll/directx/wine/wined3d/swapchain.c index cbdb961f705..b0d591a7587 100644 --- a/dll/directx/wine/wined3d/swapchain.c +++ b/dll/directx/wine/wined3d/swapchain.c @@ -33,8 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(fps); -#define GLINFO_LOCATION This->device->adapter->gl_info - /*IWineD3DSwapChain parts follow: */ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) { @@ -46,32 +44,32 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma); - /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is + /* Release the swapchain's draw buffers. Make sure This->back_buffers[0] is * the last buffer to be destroyed, FindContext() depends on that. */ - if (This->frontBuffer) + if (This->front_buffer) { - IWineD3DSurface_SetContainer(This->frontBuffer, 0); - if (IWineD3DSurface_Release(This->frontBuffer)) + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer)) { WARN("(%p) Something's still holding the front buffer (%p).\n", - This, This->frontBuffer); + This, This->front_buffer); } - This->frontBuffer = NULL; + This->front_buffer = NULL; } - if (This->backBuffer) + if (This->back_buffers) { UINT i = This->presentParms.BackBufferCount; while (i--) { - IWineD3DSurface_SetContainer(This->backBuffer[i], 0); - if (IWineD3DSurface_Release(This->backBuffer[i])) + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i])) WARN("(%p) Something's still holding back buffer %u (%p).\n", - This, i, This->backBuffer[i]); + This, i, This->back_buffers[i]); } - HeapFree(GetProcessHeap(), 0, This->backBuffer); - This->backBuffer = NULL; + HeapFree(GetProcessHeap(), 0, This->back_buffers); + This->back_buffers = NULL; } for (i = 0; i < This->num_contexts; ++i) @@ -100,11 +98,13 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * const RECT *src_rect, const RECT *dst_rect) { IWineD3DDeviceImpl *device = This->device; - IWineD3DSurfaceImpl *backbuffer = ((IWineD3DSurfaceImpl *) This->backBuffer[0]); + IWineD3DSurfaceImpl *backbuffer = This->back_buffers[0]; UINT src_w = src_rect->right - src_rect->left; UINT src_h = src_rect->bottom - src_rect->top; GLenum gl_filter; const struct wined3d_gl_info *gl_info = context->gl_info; + RECT win_rect; + UINT win_h; TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n", This, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect)); @@ -114,12 +114,14 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * else gl_filter = GL_LINEAR; - if (gl_info->fbo_ops.glBlitFramebuffer) + GetClientRect(This->win_handle, &win_rect); + win_h = win_rect.bottom - win_rect.top; + + if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format_desc->color_fixup)) { ENTER_GL(); - context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo); - context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, This->backBuffer[0]); - context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE); + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL); + glReadBuffer(GL_COLOR_ATTACHMENT0); context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL); context_set_draw_buffer(context, GL_BACK); @@ -129,8 +131,8 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * /* Note that the texture is upside down */ gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, - dst_rect->left, dst_rect->bottom, dst_rect->right, dst_rect->top, - GL_COLOR_BUFFER_BIT, gl_filter); + dst_rect->left, win_h - dst_rect->top, dst_rect->right, win_h - dst_rect->bottom, + GL_COLOR_BUFFER_BIT, gl_filter); checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n"); LEAVE_GL(); } @@ -142,7 +144,8 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * float tex_right = src_rect->right; float tex_bottom = src_rect->bottom; - context2 = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_BLIT); + context2 = context_acquire(This->device, This->back_buffers[0]); + context_apply_blit_state(context2, device); if(backbuffer->Flags & SFLAG_NORMCOORD) { @@ -152,30 +155,31 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * tex_bottom /= src_h; } + if (is_complex_fixup(backbuffer->resource.format_desc->color_fixup)) + gl_filter = GL_NEAREST; + ENTER_GL(); context_bind_fbo(context2, GL_DRAW_FRAMEBUFFER, NULL); /* Set up the texture. The surface is not in a IWineD3D*Texture container, * so there are no d3d texture settings to dirtify */ - device->blitter->set_shader((IWineD3DDevice *) device, backbuffer->resource.format_desc, - backbuffer->texture_target, backbuffer->pow2Width, - backbuffer->pow2Height); - glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + device->blitter->set_shader((IWineD3DDevice *) device, backbuffer); + glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter); + glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter); context_set_draw_buffer(context, GL_BACK); /* Set the viewport to the destination rectandle, disable any projection - * transformation set up by CTXUSAGE_BLIT, and draw a (-1,-1)-(1,1) quad. + * transformation set up by context_apply_blit_state(), and draw a + * (-1,-1)-(1,1) quad. * * Back up viewport and matrix to avoid breaking last_was_blit * - * Note that CTXUSAGE_BLIT set up viewport and ortho to match the surface - * size - we want the GL drawable(=window) size. - */ + * Note that context_apply_blit_state() set up viewport and ortho to + * match the surface size - we want the GL drawable(=window) size. */ glPushAttrib(GL_VIEWPORT_BIT); - glViewport(dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom); + glViewport(dst_rect->left, win_h - dst_rect->bottom, dst_rect->right, win_h - dst_rect->top); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -211,6 +215,7 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context * static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) { IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; + const struct wined3d_gl_info *gl_info; struct wined3d_context *context; RECT src_rect, dst_rect; BOOL render_to_fbo; @@ -219,7 +224,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride); - context = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_RESOURCELOAD); + context = context_acquire(This->device, This->back_buffers[0]); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping present.\n"); + return WINED3D_OK; + } + + gl_info = context->gl_info; /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */ if (This->device->bCursorVisible && This->device->cursorTexture) @@ -242,17 +255,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO cursor.resource.ref = 1; cursor.resource.device = This->device; cursor.resource.pool = WINED3DPOOL_SCRATCH; - cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, context->gl_info); + cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info); cursor.resource.resourceType = WINED3DRTYPE_SURFACE; cursor.texture_name = This->device->cursorTexture; cursor.texture_target = GL_TEXTURE_2D; cursor.texture_level = 0; cursor.currentDesc.Width = This->device->cursorWidth; cursor.currentDesc.Height = This->device->cursorHeight; - cursor.glRect.left = 0; - cursor.glRect.top = 0; - cursor.glRect.right = cursor.currentDesc.Width; - cursor.glRect.bottom = cursor.currentDesc.Height; /* The cursor must have pow2 sizes */ cursor.pow2Width = cursor.currentDesc.Width; cursor.pow2Height = cursor.currentDesc.Height; @@ -264,14 +273,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO if (This->presentParms.Windowed) { MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2); } - IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor, + IWineD3DSurface_Blt((IWineD3DSurface *)This->back_buffers[0], &destRect, (IWineD3DSurface *)&cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT); } if (This->device->logo_surface) { /* Blit the logo into the upper left corner of the drawable. */ - IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY); + IWineD3DSurface_BltFast((IWineD3DSurface *)This->back_buffers[0], 0, 0, + This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY); } TRACE("Presenting HDC %p.\n", context->hdc); @@ -315,8 +325,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO */ if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL); - IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INTEXTURE, NULL); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, FALSE); This->render_to_fbo = TRUE; /* Force the context manager to update the render target configuration next draw. */ @@ -420,14 +430,14 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0); } - if(!This->render_to_fbo && - ( ((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM || - ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) ) { + if (!This->render_to_fbo && ((This->front_buffer->Flags & SFLAG_INSYSMEM) + || (This->back_buffers[0]->Flags & SFLAG_INSYSMEM))) + { /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying * Doesn't work with render_to_fbo because we're not flipping */ - IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; - IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; + IWineD3DSurfaceImpl *front = This->front_buffer; + IWineD3DSurfaceImpl *back = This->back_buffers[0]; if(front->resource.size == back->resource.size) { DWORD fbflags; @@ -438,35 +448,45 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO * This serves to update the emulated overlay, if any */ fbflags = front->Flags; - IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)front, SFLAG_INDRAWABLE, TRUE); front->Flags = fbflags; } else { IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE); IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE); } - } else { - IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE); + } + else + { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->front_buffer, SFLAG_INDRAWABLE, TRUE); /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM * and INTEXTURE copies can keep their old content if they have any defined content. * If the swapeffect is COPY, the content remains the same. If it is FLIP however, * the texture / sysmem copy needs to be reloaded from the drawable */ - if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) { - IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, TRUE); + if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) + { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, TRUE); } } - if (This->device->stencilBufferTarget) + if (This->device->depth_stencil) { if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget)->Flags & SFLAG_DISCARD) + || This->device->depth_stencil->Flags & SFLAG_DISCARD) { - surface_modify_ds_location(This->device->stencilBufferTarget, SFLAG_DS_DISCARDED); + surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED, + This->device->depth_stencil->currentDesc.Width, + This->device->depth_stencil->currentDesc.Height); + if (This->device->depth_stencil == This->device->onscreen_depth_stencil) + { + IWineD3DSurface_Release((IWineD3DSurface *)This->device->onscreen_depth_stencil); + This->device->onscreen_depth_stencil = NULL; + } } } if (This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE - && context->gl_info->supported[SGI_VIDEO_SYNC]) + && gl_info->supported[SGI_VIDEO_SYNC]) { retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync)); if(retval != 0) { @@ -514,47 +534,16 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO return WINED3D_OK; } -static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) { - IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; - WINED3DLOCKED_RECT r; - BYTE *mem; +static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) +{ + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface; - if (!window || window == This->win_handle) return WINED3D_OK; + if (!window) window = swapchain->device_window; + if (window == swapchain->win_handle) return WINED3D_OK; - TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window); - if (This->context[0] == This->device->contexts[0]) - { - /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading - * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts - * and reload the resources - */ - delete_opengl_contexts((IWineD3DDevice *)This->device, iface); - This->win_handle = window; - create_primary_opengl_context((IWineD3DDevice *)This->device, iface); - } - else - { - This->win_handle = window; + TRACE("Setting swapchain %p window from %p to %p\n", swapchain, swapchain->win_handle, window); + swapchain->win_handle = window; - /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect - * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code - * So lock read only, copy the surface out, then lock with the discard flag and write back - */ - IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY); - mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - IWineD3DSurface_UnlockRect(This->backBuffer[0]); - - context_destroy(This->device, This->context[0]); - This->context[0] = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer, - This->win_handle, FALSE /* pbuffer */, &This->presentParms); - context_release(This->context[0]); - - IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD); - memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height); - HeapFree(GetProcessHeap(), 0, mem); - IWineD3DSurface_UnlockRect(This->backBuffer[0]); - } return WINED3D_OK; } @@ -599,7 +588,7 @@ static LONG fullscreen_exstyle(LONG exstyle) void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h) { IWineD3DDeviceImpl *device = swapchain->device; - HWND window = swapchain->win_handle; + HWND window = swapchain->device_window; BOOL filter_messages; LONG style, exstyle; @@ -633,7 +622,7 @@ void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, void swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain) { IWineD3DDeviceImpl *device = swapchain->device; - HWND window = swapchain->win_handle; + HWND window = swapchain->device_window; BOOL filter_messages; LONG style, exstyle; @@ -671,7 +660,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) { const struct wined3d_adapter *adapter = device->adapter; - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; BOOL displaymode_set = FALSE; WINED3DDISPLAYMODE mode; RECT client_rect; @@ -713,6 +702,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface swapchain->parent = parent; swapchain->ref = 1; swapchain->win_handle = window; + swapchain->device_window = window; if (!present_parameters->Windowed && window) { @@ -768,18 +758,19 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, - swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer); + swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, + (IWineD3DSurface **)&swapchain->front_buffer); if (FAILED(hr)) { WARN("Failed to create front buffer, hr %#x.\n", hr); goto err; } - IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain); - ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, (IWineD3DBase *)swapchain); + swapchain->front_buffer->Flags |= SFLAG_SWAPCHAIN; if (surface_type == SURFACE_OPENGL) { - IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE); } /* MSDN says we're only allowed a single fullscreen swapchain per device, @@ -816,14 +807,49 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface if (surface_type == SURFACE_OPENGL) { - swapchain->context[0] = context_create(device, (IWineD3DSurfaceImpl *)swapchain->frontBuffer, - window, FALSE /* pbuffer */, present_parameters); + WINED3DFORMAT formats[] = + { + WINED3DFMT_D24_UNORM_S8_UINT, + WINED3DFMT_D32_UNORM, + WINED3DFMT_R24_UNORM_X8_TYPELESS, + WINED3DFMT_D16_UNORM, + WINED3DFMT_S1_UINT_D15_UNORM + }; + + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + + /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. + * You are able to add a depth + stencil surface at a later stage when you need it. + * In order to support this properly in WineD3D we need the ability to recreate the opengl context and + * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new + * context, need torecreate shaders, textures and other resources. + * + * The context manager already takes care of the state problem and for the other tasks code from Reset + * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. + * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the + * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this + * issue needs to be fixed. */ + for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) + { + swapchain->ds_format = getFormatDescEntry(formats[i], gl_info); + swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format); + if (swapchain->context[0]) break; + TRACE("Depth stencil format %s is not supported, trying next format\n", + debug_d3dformat(formats[i])); + } + if (!swapchain->context[0]) { WARN("Failed to create context.\n"); hr = WINED3DERR_NOTAVAILABLE; goto err; } + + if (!present_parameters->EnableAutoDepthStencil + || swapchain->presentParms.AutoDepthStencilFormat != swapchain->ds_format->format) + { + FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); + } context_release(swapchain->context[0]); } else @@ -833,9 +859,9 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface if (swapchain->presentParms.BackBufferCount > 0) { - swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0, - sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount); - if (!swapchain->backBuffer) + swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0, + sizeof(*swapchain->back_buffers) * swapchain->presentParms.BackBufferCount); + if (!swapchain->back_buffers) { ERR("Failed to allocate backbuffer array memory.\n"); hr = E_OUTOFMEMORY; @@ -848,15 +874,16 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, - swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]); + swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, + (IWineD3DSurface **)&swapchain->back_buffers[i]); if (FAILED(hr)) { WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); goto err; } - IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain); - ((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; + IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[i], (IWineD3DBase *)swapchain); + swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN; } } @@ -864,20 +891,20 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) { TRACE("Creating depth/stencil buffer.\n"); - if (!device->auto_depth_stencil_buffer) + if (!device->auto_depth_stencil) { hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType, swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */, - &device->auto_depth_stencil_buffer); + (IWineD3DSurface **)&device->auto_depth_stencil); if (FAILED(hr)) { WARN("Failed to create the auto depth stencil, hr %#x.\n", hr); goto err; } - IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL); + IWineD3DSurface_SetContainer((IWineD3DSurface *)device->auto_depth_stencil, NULL); } } @@ -902,13 +929,13 @@ err: ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); } - if (swapchain->backBuffer) + if (swapchain->back_buffers) { for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) { - if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]); + if (swapchain->back_buffers[i]) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->back_buffers[i]); } - HeapFree(GetProcessHeap(), 0, swapchain->backBuffer); + HeapFree(GetProcessHeap(), 0, swapchain->back_buffers); } if (swapchain->context) @@ -922,7 +949,7 @@ err: HeapFree(GetProcessHeap(), 0, swapchain->context); } - if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer); + if (swapchain->front_buffer) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->front_buffer); return hr; } @@ -935,9 +962,7 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId()); - ctx = context_create(This->device, (IWineD3DSurfaceImpl *)This->frontBuffer, - This->context[0]->win_handle, FALSE /* pbuffer */, &This->presentParms); - if (!ctx) + if (!(ctx = context_create(This, This->front_buffer, This->ds_format))) { ERR("Failed to create a new context for the swapchain\n"); return NULL; @@ -962,9 +987,8 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) { - IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt; /* The drawable size of an onscreen drawable is the surface size. * (Actually: The window size, but the surface is created in window size) */ - *width = surface->currentDesc.Width; - *height = surface->currentDesc.Height; + *width = context->current_rt->currentDesc.Width; + *height = context->current_rt->currentDesc.Height; } diff --git a/dll/directx/wine/wined3d/swapchain_base.c b/dll/directx/wine/wined3d/swapchain_base.c index 4c0590e4691..1817de2079a 100644 --- a/dll/directx/wine/wined3d/swapchain_base.c +++ b/dll/directx/wine/wined3d/swapchain_base.c @@ -85,7 +85,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *i MapWindowPoints(This->win_handle, NULL, &start, 1); } - IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0); + IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, (IWineD3DSurface *)This->front_buffer, NULL, 0); return WINED3D_OK; } @@ -106,12 +106,13 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, * used (there This->backBuffer is always NULL). We need this because this function has * to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default * scissorrect dimensions. */ - if( !This->backBuffer ) { + if (!This->back_buffers) + { *ppBackBuffer = NULL; return WINED3DERR_INVALIDCALL; } - *ppBackBuffer = This->backBuffer[iBackBuffer]; + *ppBackBuffer = (IWineD3DSurface *)This->back_buffers[iBackBuffer]; TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer); /* Note inc ref on returned surface */ @@ -145,15 +146,14 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface return hr; } -HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) { +HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice **device) +{ IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; - *ppDevice = (IWineD3DDevice *)This->device; + *device = (IWineD3DDevice *)This->device; + IWineD3DDevice_AddRef(*device); - /* Note Calling this method will increase the internal reference count - on the IDirect3DDevice9 interface. */ - IWineD3DDevice_AddRef(*ppDevice); - TRACE("(%p) : returning %p\n", This, *ppDevice); + TRACE("(%p) : returning %p\n", This, *device); return WINED3D_OK; } @@ -171,9 +171,9 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; HDC hDC; TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags); - hDC = GetDC(This->win_handle); + hDC = GetDC(This->device_window); SetDeviceGammaRamp(hDC, (LPVOID)pRamp); - ReleaseDC(This->win_handle, hDC); + ReleaseDC(This->device_window, hDC); return WINED3D_OK; } @@ -183,9 +183,9 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface; HDC hDC; TRACE("(%p) : pRamp@%p\n", This, pRamp); - hDC = GetDC(This->win_handle); + hDC = GetDC(This->device_window); GetDeviceGammaRamp(hDC, pRamp); - ReleaseDC(This->win_handle, hDC); + ReleaseDC(This->device_window, hDC); return WINED3D_OK; } diff --git a/dll/directx/wine/wined3d/swapchain_gdi.c b/dll/directx/wine/wined3d/swapchain_gdi.c index c437b419f8e..b80352c1dce 100644 --- a/dll/directx/wine/wined3d/swapchain_gdi.c +++ b/dll/directx/wine/wined3d/swapchain_gdi.c @@ -37,24 +37,27 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma); /* release the ref to the front and back buffer parents */ - if(This->frontBuffer) { - IWineD3DSurface_SetContainer(This->frontBuffer, 0); - if (IWineD3DSurface_Release(This->frontBuffer) > 0) + if (This->front_buffer) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer) > 0) { WARN("(%p) Something's still holding the front buffer\n",This); } } - if(This->backBuffer) { + if (This->back_buffers) + { UINT i; - for(i = 0; i < This->presentParms.BackBufferCount; i++) { - IWineD3DSurface_SetContainer(This->backBuffer[i], 0); - if (IWineD3DSurface_Release(This->backBuffer[i]) > 0) + for (i = 0; i < This->presentParms.BackBufferCount; ++i) + { + IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL); + if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i])) { WARN("(%p) Something's still holding the back buffer\n",This); } } - HeapFree(GetProcessHeap(), 0, This->backBuffer); + HeapFree(GetProcessHeap(), 0, This->back_buffers); } /* Restore the screen resolution if we rendered in fullscreen @@ -86,7 +89,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) *****************************************************************************/ void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) { - IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; + IWineD3DSurfaceImpl *front = This->front_buffer; if(front->resource.usage & WINED3DUSAGE_RENDERTARGET) { POINT offset = {0,0}; @@ -172,12 +175,13 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CO IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface; IWineD3DSurfaceImpl *front, *back; - if(!This->backBuffer) { + if (!This->back_buffers) + { WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; } - front = (IWineD3DSurfaceImpl *) This->frontBuffer; - back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; + front = This->front_buffer; + back = This->back_buffers[0]; /* Flip the DC */ { @@ -226,7 +230,7 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CO /* FPS support */ if (TRACE_ON(fps)) { - static long prev_time, frames; + static LONG prev_time, frames; DWORD time = GetTickCount(); frames++; diff --git a/dll/directx/wine/wined3d/texture.c b/dll/directx/wine/wined3d/texture.c index 1e272144a8a..98e7909370e 100644 --- a/dll/directx/wine/wined3d/texture.c +++ b/dll/directx/wine/wined3d/texture.c @@ -63,21 +63,22 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG { /* context_acquire() sets isInDraw to TRUE when loading a pbuffer into a texture, * thus no danger of recursive calls. */ - context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + context = context_acquire(device, NULL); } if (This->resource.format_desc->format == WINED3DFMT_P8_UINT || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[i])) + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + if (palette9_changed(surface)) { TRACE("Reloading surface because the d3d8/9 palette was changed.\n"); /* TODO: This is not necessarily needed with hw palettized texture support. */ - IWineD3DSurface_LoadLocation(This->surfaces[i], SFLAG_INSYSMEM, NULL); + IWineD3DSurface_LoadLocation((IWineD3DSurface *)surface, SFLAG_INSYSMEM, NULL); /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */ - IWineD3DSurface_ModifyLocation(This->surfaces[i], SFLAG_INTEXTURE, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)surface, SFLAG_INTEXTURE, FALSE); } } } @@ -86,9 +87,9 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG * since the last load then reload the surfaces. */ if (*dirty) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode); + IWineD3DSurface_LoadTexture((IWineD3DSurface *)This->baseTexture.sub_resources[i], srgb_mode); } } else @@ -108,17 +109,18 @@ static void texture_cleanup(IWineD3DTextureImpl *This) TRACE("(%p) : Cleaning up\n", This); - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - if (This->surfaces[i]) + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + if (surface) { /* Clean out the texture name we gave to the surface so that the * surface doesn't try and release it */ - surface_set_texture_name(This->surfaces[i], 0, TRUE); - surface_set_texture_name(This->surfaces[i], 0, FALSE); - surface_set_texture_target(This->surfaces[i], 0); - IWineD3DSurface_SetContainer(This->surfaces[i], 0); - IWineD3DSurface_Release(This->surfaces[i]); + surface_set_texture_name(surface, 0, TRUE); + surface_set_texture_name(surface, 0, FALSE); + surface_set_texture_target(surface, 0); + IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL); + IWineD3DSurface_Release((IWineD3DSurface *)surface); } } @@ -204,10 +206,12 @@ static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) { * surface before, this one will be a NOP and vice versa. Unloading an unloaded * surface is fine */ - for (i = 0; i < This->baseTexture.levels; i++) { - IWineD3DSurface_UnLoad(This->surfaces[i]); - surface_set_texture_name(This->surfaces[i], 0, FALSE); /* Delete rgb name */ - surface_set_texture_name(This->surfaces[i], 0, TRUE); /* delete srgb name */ + for (i = 0; i < This->baseTexture.level_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + IWineD3DSurface_UnLoad((IWineD3DSurface *)surface); + surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */ + surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */ } basetexture_unload((IWineD3DBaseTexture *)iface); @@ -276,14 +280,20 @@ static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BO gl_tex = &This->baseTexture.texture_rgb; } - for (i = 0; i < This->baseTexture.levels; ++i) { - surface_set_texture_name(This->surfaces[i], gl_tex->name, This->baseTexture.is_srgb); + for (i = 0; i < This->baseTexture.level_count; ++i) + { + IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i]; + surface_set_texture_name(surface, gl_tex->name, This->baseTexture.is_srgb); } - /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect - * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something - * that prevents us from hitting the accelerated codepath. Thus manually set the GL state. The same applies to filtering. - * Even if the texture has only one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW fallback on macos. - */ + + /* Conditinal non power of two textures use a different clamping + * default. If we're using the GL_WINE_normalized_texrect partial + * driver emulation, we're dealing with a GL_TEXTURE_2D texture which + * has the address mode set to repeat - something that prevents us + * from hitting the accelerated codepath. Thus manually set the GL + * state. The same applies to filtering. Even if the texture has only + * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW + * fallback on macos. */ if(IWineD3DBaseTexture_IsCondNP2(iface)) { ENTER_GL(); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -323,72 +333,94 @@ static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) { /* ******************************************* IWineD3DTexture IWineD3DTexture parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; +static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT level, WINED3DSURFACE_DESC *desc) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - TRACE("(%p) Level (%d)\n", This, Level); - return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc); + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + + return IWineD3DSurface_GetDesc(surface, desc); } -static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, UINT Level, IWineD3DSurface** ppSurfaceLevel) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, + UINT level, IWineD3DSurface **surface) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *s; - if (Level < This->baseTexture.levels) { - *ppSurfaceLevel = This->surfaces[Level]; - IWineD3DSurface_AddRef(This->surfaces[Level]); - hr = WINED3D_OK; - TRACE("(%p) : returning %p for level %d\n", This, *ppSurfaceLevel, Level); + TRACE("iface %p, level %u, surface %p.\n", iface, level, surface); + + if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if (WINED3D_OK != hr) { - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - *ppSurfaceLevel = NULL; /* Just to be on the safe side.. */ - } - return hr; + + IWineD3DSurface_AddRef(s); + *surface = s; + + TRACE("Returning surface %p.\n", *surface); + + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, UINT Level, WINED3DLOCKED_RECT *pLockedRect, - CONST RECT *pRect, DWORD Flags) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, + UINT level, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - hr = IWineD3DSurface_LockRect(This->surfaces[Level], pLockedRect, pRect, Flags); - } - if (WINED3D_OK == hr) { - TRACE("(%p) Level (%d) success\n", This, Level); - } else { - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); + TRACE("iface %p, level %u, locked_rect %p, rect %s, flags %#x.\n", + iface, level, locked_rect, wine_dbgstr_rect(rect), flags); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + return IWineD3DSurface_LockRect(surface, locked_rect, rect, flags); } -static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT Level) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - HRESULT hr = WINED3DERR_INVALIDCALL; +static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT level) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurface *surface; - if (Level < This->baseTexture.levels) { - hr = IWineD3DSurface_UnlockRect(This->surfaces[Level]); + TRACE("iface %p, level %u.\n", iface, level); + + if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - if ( WINED3D_OK == hr) { - TRACE("(%p) Level (%d) success\n", This, Level); - } else { - WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - } - return hr; + + return IWineD3DSurface_UnlockRect(surface); } -static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) { - IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; - This->baseTexture.texture_rgb.dirty = TRUE; - This->baseTexture.texture_srgb.dirty = TRUE; - TRACE("(%p) : dirtyfication of surface Level (0)\n", This); - surface_add_dirty_rect(This->surfaces[0], pDirtyRect); +static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, const RECT *dirty_rect) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DSurfaceImpl *surface; + + TRACE("iface %p, dirty_rect %s.\n", iface, wine_dbgstr_rect(dirty_rect)); + + if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, 0, 0))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; + } + + texture->baseTexture.texture_rgb.dirty = TRUE; + texture->baseTexture.texture_srgb.dirty = TRUE; + surface_add_dirty_rect(surface, dirty_rect); return WINED3D_OK; } @@ -434,7 +466,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT pow2_width, pow2_height; UINT tmp_w, tmp_h; unsigned int i; @@ -497,8 +529,8 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT texture->lpVtbl = &IWineD3DTexture_Vtbl; - hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_TEXTURE, - device, 0, usage, format_desc, pool, parent, parent_ops); + hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 1, levels, + WINED3DRTYPE_TEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x.\n", hr); @@ -565,22 +597,24 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT /* Generate all the surfaces. */ tmp_w = width; tmp_h = height; - for (i = 0; i < texture->baseTexture.levels; ++i) + for (i = 0; i < texture->baseTexture.level_count; ++i) { + IWineD3DSurface *surface; + /* Use the callback to create the texture surface. */ hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format, - usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]); - if (FAILED(hr) || ((IWineD3DSurfaceImpl *)texture->surfaces[i])->Flags & SFLAG_OVERSIZE) + usage, pool, i, 0, &surface); + if (FAILED(hr)) { FIXME("Failed to create surface %p, hr %#x\n", texture, hr); - texture->surfaces[i] = NULL; texture_cleanup(texture); return hr; } - IWineD3DSurface_SetContainer(texture->surfaces[i], (IWineD3DBase *)texture); - TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[i]); - surface_set_texture_target(texture->surfaces[i], texture->target); + IWineD3DSurface_SetContainer(surface, (IWineD3DBase *)texture); + surface_set_texture_target((IWineD3DSurfaceImpl *)surface, texture->target); + texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)surface; + TRACE("Created surface level %u @ %p.\n", i, surface); /* Calculate the next mipmap level. */ tmp_w = max(1, tmp_w >> 1); tmp_h = max(1, tmp_h >> 1); diff --git a/dll/directx/wine/wined3d/utils.c b/dll/directx/wine/wined3d/utils.c index 2ff16752c33..b63a5f8cee8 100644 --- a/dll/directx/wine/wined3d/utils.c +++ b/dll/directx/wine/wined3d/utils.c @@ -141,31 +141,40 @@ struct wined3d_format_base_flags static const struct wined3d_format_base_flags format_base_flags[] = { - {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC}, - {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC}, - {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_UYVY, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_YUY2, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_YV12, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT1, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT2, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT3, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT4, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_DXT5, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_MULTI2_ARGB8, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_G8R8_G8B8, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_R8G8_B8G8, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC}, + {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_NVHU, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_NVHS, WINED3DFMT_FLAG_FOURCC}, + {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, }; struct wined3d_format_compression_info @@ -183,7 +192,7 @@ static const struct wined3d_format_compression_info format_compression_info[] = {WINED3DFMT_DXT3, 4, 4, 16}, {WINED3DFMT_DXT4, 4, 4, 16}, {WINED3DFMT_DXT5, 4, 4, 16}, - {WINED3DFMT_ATI2N, 4, 4, 16}, + {WINED3DFMT_ATI2N, 1, 1, 1}, }; struct wined3d_format_vertex_info @@ -218,20 +227,328 @@ static const struct wined3d_format_vertex_info format_vertex_info[] = {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)} }; -typedef struct { - WINED3DFORMAT fmt; - GLint glInternal, glGammaInternal, rtInternal, glFormat, glType; - unsigned int Flags; +struct wined3d_format_texture_info +{ + WINED3DFORMAT format; + GLint gl_internal; + GLint gl_srgb_internal; + GLint gl_rt_internal; + GLint gl_format; + GLint gl_type; + unsigned int conv_byte_count; + unsigned int flags; GL_SupportedExt extension; -} GlPixelFormatDescTemplate; + void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); +}; -/***************************************************************************** - * OpenGL format template. Contains unexciting formats which do not need - * extension checks. The order in this table is independent of the order in - * the table StaticPixelFormatDesc above. Not all formats have to be in this - * table. - */ -static const GlPixelFormatDescTemplate gl_formats_template[] = { +static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not + * format+type combination to load it. Thus convert it to A8L8, then load it + * with A4L4 internal, but A8L8 format+type + */ + unsigned int x, y; + const unsigned char *Source; + unsigned char *Dest; + UINT outpitch = pitch * 2; + + for(y = 0; y < height; y++) { + Source = src + y * pitch; + Dest = dst + y * outpitch; + for (x = 0; x < width; x++ ) { + unsigned char color = (*Source++); + /* A */ Dest[1] = (color & 0xf0) << 0; + /* L */ Dest[0] = (color & 0x0f) << 4; + Dest += 2; + } + } +} + +static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const WORD *Source; + + for(y = 0; y < height; y++) + { + unsigned short *Dest_s = (unsigned short *) (dst + y * pitch); + Source = (const WORD *)(src + y * pitch); + for (x = 0; x < width; x++ ) + { + short color = (*Source++); + unsigned char l = ((color >> 10) & 0xfc); + short v = ((color >> 5) & 0x3e); + short u = ((color ) & 0x1f); + short v_conv = v + 16; + short u_conv = u + 16; + + *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f); + Dest_s += 1; + } + } +} + +static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const WORD *Source; + unsigned char *Dest; + UINT outpitch = (pitch * 3)/2; + + /* This makes the gl surface bigger(24 bit instead of 16), but it works with + * fixed function and shaders without further conversion once the surface is + * loaded + */ + for(y = 0; y < height; y++) { + Source = (const WORD *)(src + y * pitch); + Dest = dst + y * outpitch; + for (x = 0; x < width; x++ ) { + short color = (*Source++); + unsigned char l = ((color >> 10) & 0xfc); + char v = ((color >> 5) & 0x3e); + char u = ((color ) & 0x1f); + + /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign + * and doubles the positive range. Thus shift left only once, gl does the 2nd + * shift. GL reads a signed value and converts it into an unsigned value. + */ + /* M */ Dest[2] = l << 1; + + /* Those are read as signed, but kept signed. Just left-shift 3 times to scale + * from 5 bit values to 8 bit values. + */ + /* V */ Dest[1] = v << 3; + /* U */ Dest[0] = u << 3; + Dest += 3; + } + } +} + +static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const short *Source; + unsigned char *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const short *)(src + y * pitch); + Dest = dst + y * outpitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = 0xff; + /* G */ Dest[1] = (color >> 8) + 128; /* V */ + /* R */ Dest[2] = (color) + 128; /* U */ + Dest += 3; + } + } +} + +static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned char *Dest; + + /* Doesn't work correctly with the fixed function pipeline, but can work in + * shaders if the shader is adjusted. (There's no use for this format in gl's + * standard fixed function pipeline anyway). + */ + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = dst + y * pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */ + /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + Dest += 4; + } + } +} + +static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned char *Dest; + + /* This implementation works with the fixed function pipeline and shaders + * without further modification after converting the surface. + */ + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = dst + y * pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */ + /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */ + /* U */ Dest[0] = (color & 0xff); /* U */ + /* I */ Dest[3] = 255; /* X */ + Dest += 4; + } + } +} + +static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned char *Dest; + + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = dst + y * pitch; + for (x = 0; x < width; x++ ) + { + LONG color = (*Source++); + /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */ + /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */ + /* R */ Dest[2] = (color & 0xff) + 128; /* U */ + /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */ + Dest += 4; + } + } +} + +static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const DWORD *Source; + unsigned short *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const DWORD *)(src + y * pitch); + Dest = (unsigned short *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) + { + DWORD color = (*Source++); + /* B */ Dest[0] = 0xffff; + /* G */ Dest[1] = (color >> 16) + 32768; /* V */ + /* R */ Dest[2] = (color ) + 32768; /* U */ + Dest += 3; + } + } +} + +static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const WORD *Source; + WORD *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const WORD *)(src + y * pitch); + Dest = (WORD *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) + { + WORD green = (*Source++); + WORD red = (*Source++); + Dest[0] = green; + Dest[1] = red; + /* Strictly speaking not correct for R16G16F, but it doesn't matter because the + * shader overwrites it anyway + */ + Dest[2] = 0xffff; + Dest += 3; + } + } +} + +static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + const float *Source; + float *Dest; + UINT outpitch = (pitch * 3)/2; + + for(y = 0; y < height; y++) + { + Source = (const float *)(src + y * pitch); + Dest = (float *) (dst + y * outpitch); + for (x = 0; x < width; x++ ) + { + float green = (*Source++); + float red = (*Source++); + Dest[0] = green; + Dest[1] = red; + Dest[2] = 1.0f; + Dest += 3; + } + } +} + +static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + UINT outpitch = pitch * 2; + + for (y = 0; y < height; ++y) + { + const WORD *source = (const WORD *)(src + y * pitch); + DWORD *dest = (DWORD *)(dst + y * outpitch); + + for (x = 0; x < width; ++x) + { + /* The depth data is normalized, so needs to be scaled, + * the stencil data isn't. Scale depth data by + * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */ + WORD d15 = source[x] >> 1; + DWORD d24 = (d15 << 9) + (d15 >> 6); + dest[x] = (d24 << 8) | (source[x] & 0x1); + } + } +} + +static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + + for (y = 0; y < height; ++y) + { + const DWORD *source = (const DWORD *)(src + y * pitch); + DWORD *dest = (DWORD *)(dst + y * pitch); + + for (x = 0; x < width; ++x) + { + /* Just need to clear out the X4 part. */ + dest[x] = source[x] & ~0xf0; + } + } +} + +static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height) +{ + unsigned int x, y; + UINT outpitch = pitch * 2; + + for (y = 0; y < height; ++y) + { + const DWORD *source = (const DWORD *)(src + y * pitch); + float *dest_f = (float *)(dst + y * outpitch); + DWORD *dest_s = (DWORD *)(dst + y * outpitch); + + for (x = 0; x < width; ++x) + { + dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8); + dest_s[x * 2 + 1] = source[x] & 0xff; + } + } +} + +static const struct wined3d_format_texture_info format_texture_info[] = +{ /* WINED3DFORMAT internal srgbInternal rtInternal format type flags @@ -244,289 +561,296 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = { * endian machine */ {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, - GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, + GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_APPLE, 0, WINED3DFMT_FLAG_FILTERING, - APPLE_YCBCR_422}, + APPLE_YCBCR_422, NULL}, {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, - GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, + GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE, 0, WINED3DFMT_FLAG_FILTERING, - APPLE_YCBCR_422}, + APPLE_YCBCR_422, NULL}, {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, + GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0, - GL_RGBA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - EXT_TEXTURE_COMPRESSION_S3TC}, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, /* IEEE formats */ {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, - GL_RED, GL_FLOAT, + GL_RED, GL_FLOAT, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, NULL}, {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0, - GL_RED, GL_FLOAT, + GL_RED, GL_FLOAT, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, - GL_RGB, GL_FLOAT, + GL_RGB, GL_FLOAT, 12, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, &convert_r32g32_float}, {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0, - GL_RG, GL_FLOAT, + GL_RG, GL_FLOAT, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0, - GL_RGBA, GL_FLOAT, - WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + GL_RGBA, GL_FLOAT, 0, + WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, + ARB_TEXTURE_FLOAT, NULL}, /* Float */ {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, - GL_RED, GL_HALF_FLOAT_ARB, + GL_RED, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, NULL}, {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0, - GL_RED, GL_HALF_FLOAT_ARB, + GL_RED, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0, - GL_RGB, GL_HALF_FLOAT_ARB, + GL_RGB, GL_HALF_FLOAT_ARB, 6, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, &convert_r16g16}, {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0, - GL_RG, GL_HALF_FLOAT_ARB, + GL_RG, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_RG}, + ARB_TEXTURE_RG, NULL}, {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0, - GL_RGBA, GL_HALF_FLOAT_ARB, + GL_RGBA, GL_HALF_FLOAT_ARB, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET, - ARB_TEXTURE_FLOAT}, + ARB_TEXTURE_FLOAT, NULL}, /* Palettized formats */ {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0, - GL_RGBA, GL_UNSIGNED_BYTE, + GL_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - ARB_FRAGMENT_PROGRAM}, + ARB_FRAGMENT_PROGRAM, NULL}, {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0, - GL_COLOR_INDEX, GL_UNSIGNED_BYTE, + GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0, 0, - EXT_PALETTED_TEXTURE}, + EXT_PALETTED_TEXTURE, NULL}, /* Standard ARGB formats */ {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0, - GL_BGR, GL_UNSIGNED_BYTE, + GL_BGR, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET + | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET + | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0, - GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, + GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0, - GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, + GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0, - GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0, - GL_RGB, GL_UNSIGNED_BYTE_3_3_2, + GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, + GL_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0, - GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, + GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, - GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, + GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16, - GL_RGB, GL_UNSIGNED_SHORT, + GL_RGB, GL_UNSIGNED_SHORT, 6, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, &convert_r16g16}, {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0, - GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, + GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0, - GL_RGBA, GL_UNSIGNED_SHORT, + GL_RGBA, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, /* Luminance */ {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0, - GL_LUMINANCE, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2, 0, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, &convert_l4a4_unorm}, /* Bump mapping stuff */ {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0, - GL_BGR, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGR, GL_UNSIGNED_BYTE, 3, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r8g8_snorm}, {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0, - GL_DSDT_NV, GL_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_DSDT_NV, GL_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, NULL}, {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0, - GL_RGB, GL_UNSIGNED_SHORT_5_6_5, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r5g5_snorm_l6_unorm}, {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0, - GL_DSDT_MAG_NV, GL_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_DSDT_MAG_NV, GL_BYTE, 3, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, &convert_r5g5_snorm_l6_unorm_nv}, {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0, - GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r8g8_snorm_l8x8_unorm}, {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0, - GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, &convert_r8g8_snorm_l8x8_unorm_nv}, {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0, - GL_BGRA, GL_UNSIGNED_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGRA, GL_UNSIGNED_BYTE, 4, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r8g8b8a8_snorm}, {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0, - GL_RGBA, GL_BYTE, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_RGBA, GL_BYTE, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, NULL}, {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0, - GL_BGR, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + GL_BGR, GL_UNSIGNED_SHORT, 6, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + WINED3D_GL_EXT_NONE, &convert_r16g16_snorm}, {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0, - GL_HILO_NV, GL_SHORT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - NV_TEXTURE_SHADER}, + GL_HILO_NV, GL_SHORT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP, + NV_TEXTURE_SHADER, NULL}, /* Depth stencil formats */ {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, - GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - EXT_PACKED_DEPTH_STENCIL}, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + EXT_PACKED_DEPTH_STENCIL, &convert_s1_uint_d15_unorm}, {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_FRAMEBUFFER_OBJECT}, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_FRAMEBUFFER_OBJECT, &convert_s1_uint_d15_unorm}, {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, - GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - EXT_PACKED_DEPTH_STENCIL}, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + EXT_PACKED_DEPTH_STENCIL, NULL}, {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_FRAMEBUFFER_OBJECT}, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_FRAMEBUFFER_OBJECT, NULL}, {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0, - GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - EXT_PACKED_DEPTH_STENCIL}, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + EXT_PACKED_DEPTH_STENCIL, &convert_s4x4_uint_d24_unorm}, {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_FRAMEBUFFER_OBJECT}, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_FRAMEBUFFER_OBJECT, &convert_s4x4_uint_d24_unorm}, {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0, - GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, - WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_TEXTURE}, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, + WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH + | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_TEXTURE, NULL}, {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0, - GL_LUMINANCE, GL_UNSIGNED_SHORT, + GL_LUMINANCE, GL_UNSIGNED_SHORT, 0, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, - WINED3D_GL_EXT_NONE}, + WINED3D_GL_EXT_NONE, NULL}, {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0, - GL_DEPTH_COMPONENT, GL_FLOAT, - WINED3DFMT_FLAG_DEPTH, - ARB_DEPTH_BUFFER_FLOAT}, + GL_DEPTH_COMPONENT, GL_FLOAT, 0, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_BUFFER_FLOAT, NULL}, {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0, - GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, - WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL, - ARB_DEPTH_BUFFER_FLOAT}, + GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, + WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW, + ARB_DEPTH_BUFFER_FLOAT, &convert_s8_uint_d24_float}, /* Vendor-specific formats */ {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - ATI_TEXTURE_COMPRESSION_3DC}, + ATI_TEXTURE_COMPRESSION_3DC, NULL}, {WINED3DFMT_ATI2N, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 0, - EXT_TEXTURE_COMPRESSION_RGTC}, + EXT_TEXTURE_COMPRESSION_RGTC, NULL}, }; static inline int getFmtIdx(WINED3DFORMAT fmt) { @@ -560,7 +884,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info) for (i = 0; i < format_count; ++i) { - struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i]; + struct wined3d_format_desc *desc = &gl_info->gl_formats[i]; desc->format = formats[i].format; desc->red_mask = formats[i].redMask; desc->green_mask = formats[i].greenMask; @@ -595,7 +919,7 @@ static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info) for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i) { - struct GlPixelFormatDesc *format_desc; + struct wined3d_format_desc *format_desc; int fmt_idx = getFmtIdx(format_compression_info[i].format); if (fmt_idx == -1) @@ -616,7 +940,7 @@ static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info) } /* Context activation is done by the caller. */ -static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc) +static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format_desc *format_desc) { /* Check if the default internal format is supported as a frame buffer * target, otherwise fall back to the render target internal. @@ -755,7 +1079,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info) for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i) { - struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i]; + struct wined3d_format_desc *desc = &gl_info->gl_formats[i]; if (!desc->glInternal) continue; @@ -798,29 +1122,33 @@ static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info) { unsigned int i; - for (i = 0; i < sizeof(gl_formats_template) / sizeof(gl_formats_template[0]); ++i) + for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i) { - int fmt_idx = getFmtIdx(gl_formats_template[i].fmt); - struct GlPixelFormatDesc *desc; + int fmt_idx = getFmtIdx(format_texture_info[i].format); + struct wined3d_format_desc *desc; if (fmt_idx == -1) { ERR("Format %s (%#x) not found.\n", - debug_d3dformat(gl_formats_template[i].fmt), gl_formats_template[i].fmt); + debug_d3dformat(format_texture_info[i].format), format_texture_info[i].format); return FALSE; } - if (!gl_info->supported[gl_formats_template[i].extension]) continue; + if (!gl_info->supported[format_texture_info[i].extension]) continue; desc = &gl_info->gl_formats[fmt_idx]; - desc->glInternal = gl_formats_template[i].glInternal; - desc->glGammaInternal = gl_formats_template[i].glGammaInternal; - desc->rtInternal = gl_formats_template[i].rtInternal; - desc->glFormat = gl_formats_template[i].glFormat; - desc->glType = gl_formats_template[i].glType; + desc->glInternal = format_texture_info[i].gl_internal; + desc->glGammaInternal = format_texture_info[i].gl_srgb_internal; + desc->rtInternal = format_texture_info[i].gl_rt_internal; + desc->glFormat = format_texture_info[i].gl_format; + desc->glType = format_texture_info[i].gl_type; desc->color_fixup = COLOR_FIXUP_IDENTITY; - desc->Flags |= gl_formats_template[i].Flags; + desc->Flags |= format_texture_info[i].flags; desc->heightscale = 1.0f; + + /* Texture conversion stuff */ + desc->convert = format_texture_info[i].convert; + desc->conv_byte_count = format_texture_info[i].conv_byte_count; } return TRUE; @@ -938,6 +1266,7 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal) static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) { + struct wined3d_format_desc *desc; unsigned int fmt_idx, i; WINED3DFORMAT fmts16[] = { WINED3DFMT_R16_FLOAT, @@ -945,7 +1274,6 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3 WINED3DFMT_R16G16B16A16_FLOAT, }; BOOL filtered; - struct GlPixelFormatDesc *desc; if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) { @@ -1043,6 +1371,7 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info) idx = getFmtIdx(WINED3DFMT_R8G8_SNORM); gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc( 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); + idx = getFmtIdx(WINED3DFMT_R16G16_SNORM); gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc( 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE); @@ -1098,8 +1427,11 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info) gl_info->gl_formats[idx].heightscale = 1.5f; gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12); - idx = getFmtIdx(WINED3DFMT_P8_UINT); - gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); + if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM]) + { + idx = getFmtIdx(WINED3DFMT_P8_UINT); + gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8); + } if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA]) { @@ -1125,7 +1457,7 @@ static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info) for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i) { - struct GlPixelFormatDesc *format_desc; + struct wined3d_format_desc *format_desc; int fmt_idx = getFmtIdx(format_vertex_info[i].format); if (fmt_idx == -1) @@ -1182,7 +1514,7 @@ fail: return FALSE; } -const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info) +const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info) { int idx = getFmtIdx(fmt); @@ -1485,9 +1817,7 @@ const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) { const char* debug_d3drenderstate(DWORD state) { switch (state) { #define D3DSTATE_TO_STR(u) case u: return #u - D3DSTATE_TO_STR(WINED3DRS_TEXTUREHANDLE ); D3DSTATE_TO_STR(WINED3DRS_ANTIALIAS ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESS ); D3DSTATE_TO_STR(WINED3DRS_TEXTUREPERSPECTIVE ); D3DSTATE_TO_STR(WINED3DRS_WRAPU ); D3DSTATE_TO_STR(WINED3DRS_WRAPV ); @@ -1501,11 +1831,8 @@ const char* debug_d3drenderstate(DWORD state) { D3DSTATE_TO_STR(WINED3DRS_ZWRITEENABLE ); D3DSTATE_TO_STR(WINED3DRS_ALPHATESTENABLE ); D3DSTATE_TO_STR(WINED3DRS_LASTPIXEL ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAG ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREMIN ); D3DSTATE_TO_STR(WINED3DRS_SRCBLEND ); D3DSTATE_TO_STR(WINED3DRS_DESTBLEND ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREMAPBLEND ); D3DSTATE_TO_STR(WINED3DRS_CULLMODE ); D3DSTATE_TO_STR(WINED3DRS_ZFUNC ); D3DSTATE_TO_STR(WINED3DRS_ALPHAREF ); @@ -1526,9 +1853,6 @@ const char* debug_d3drenderstate(DWORD state) { D3DSTATE_TO_STR(WINED3DRS_STIPPLEENABLE ); D3DSTATE_TO_STR(WINED3DRS_EDGEANTIALIAS ); D3DSTATE_TO_STR(WINED3DRS_COLORKEYENABLE ); - D3DSTATE_TO_STR(WINED3DRS_BORDERCOLOR ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSU ); - D3DSTATE_TO_STR(WINED3DRS_TEXTUREADDRESSV ); D3DSTATE_TO_STR(WINED3DRS_MIPMAPLODBIAS ); D3DSTATE_TO_STR(WINED3DRS_ZBIAS ); D3DSTATE_TO_STR(WINED3DRS_RANGEFOGENABLE ); @@ -1544,38 +1868,6 @@ const char* debug_d3drenderstate(DWORD state) { D3DSTATE_TO_STR(WINED3DRS_STENCILMASK ); D3DSTATE_TO_STR(WINED3DRS_STENCILWRITEMASK ); D3DSTATE_TO_STR(WINED3DRS_TEXTUREFACTOR ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN00 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN01 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN02 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN03 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN04 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN05 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN06 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN07 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN08 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN09 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN10 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN11 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN12 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN13 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN14 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN15 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN16 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN17 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN18 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN19 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN20 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN21 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN22 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN23 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN24 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN25 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN26 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN27 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN28 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN29 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN30 ); - D3DSTATE_TO_STR(WINED3DRS_STIPPLEPATTERN31 ); D3DSTATE_TO_STR(WINED3DRS_WRAP0 ); D3DSTATE_TO_STR(WINED3DRS_WRAP1 ); D3DSTATE_TO_STR(WINED3DRS_WRAP2 ); @@ -2125,7 +2417,7 @@ unsigned int count_bits(unsigned int mask) /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB. * The later function requires individual color components. */ -BOOL getColorBits(const struct GlPixelFormatDesc *format_desc, +BOOL getColorBits(const struct wined3d_format_desc *format_desc, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize) { TRACE("fmt: %s\n", debug_d3dformat(format_desc->format)); @@ -2162,7 +2454,7 @@ BOOL getColorBits(const struct GlPixelFormatDesc *format_desc, } /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */ -BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *depthSize, short *stencilSize) +BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize) { TRACE("fmt: %s\n", debug_d3dformat(format_desc->format)); switch(format_desc->format) @@ -2190,6 +2482,115 @@ BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *dep return TRUE; } +DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) +{ + unsigned int r, g, b, a; + DWORD ret; + + if (destfmt == WINED3DFMT_B8G8R8A8_UNORM + || destfmt == WINED3DFMT_B8G8R8X8_UNORM + || destfmt == WINED3DFMT_B8G8R8_UNORM) + return color; + + TRACE("Converting color %08x to format %s\n", color, debug_d3dformat(destfmt)); + + a = (color & 0xff000000) >> 24; + r = (color & 0x00ff0000) >> 16; + g = (color & 0x0000ff00) >> 8; + b = (color & 0x000000ff) >> 0; + + switch(destfmt) + { + case WINED3DFMT_B5G6R5_UNORM: + if(r == 0xff && g == 0xff && b == 0xff) return 0xffff; + r = (r * 32) / 256; + g = (g * 64) / 256; + b = (b * 32) / 256; + ret = r << 11; + ret |= g << 5; + ret |= b; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_B5G5R5X1_UNORM: + case WINED3DFMT_B5G5R5A1_UNORM: + a = (a * 2) / 256; + r = (r * 32) / 256; + g = (g * 32) / 256; + b = (b * 32) / 256; + ret = a << 15; + ret |= r << 10; + ret |= g << 5; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_A8_UNORM: + TRACE("Returning %08x\n", a); + return a; + + case WINED3DFMT_B4G4R4X4_UNORM: + case WINED3DFMT_B4G4R4A4_UNORM: + a = (a * 16) / 256; + r = (r * 16) / 256; + g = (g * 16) / 256; + b = (b * 16) / 256; + ret = a << 12; + ret |= r << 8; + ret |= g << 4; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_B2G3R3_UNORM: + r = (r * 8) / 256; + g = (g * 8) / 256; + b = (b * 4) / 256; + ret = r << 5; + ret |= g << 2; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_R8G8B8X8_UNORM: + case WINED3DFMT_R8G8B8A8_UNORM: + ret = a << 24; + ret |= b << 16; + ret |= g << 8; + ret |= r << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_B10G10R10A2_UNORM: + a = (a * 4) / 256; + r = (r * 1024) / 256; + g = (g * 1024) / 256; + b = (b * 1024) / 256; + ret = a << 30; + ret |= r << 20; + ret |= g << 10; + ret |= b << 0; + TRACE("Returning %08x\n", ret); + return ret; + + case WINED3DFMT_R10G10B10A2_UNORM: + a = (a * 4) / 256; + r = (r * 1024) / 256; + g = (g * 1024) / 256; + b = (b * 1024) / 256; + ret = a << 30; + ret |= b << 20; + ret |= g << 10; + ret |= r << 0; + TRACE("Returning %08x\n", ret); + return ret; + + default: + FIXME("Add a COLORFILL conversion for format %s\n", debug_d3dformat(destfmt)); + return 0; + } +} + /* DirectDraw stuff */ WINED3DFORMAT pixelformat_for_depth(DWORD depth) { switch(depth) { @@ -2258,147 +2659,6 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { return size; } -/*********************************************************************** - * CalculateTexRect - * - * Calculates the dimensions of the opengl texture used for blits. - * Handled oversized opengl textures and updates the source rectangle - * accordingly - * - * Params: - * This: Surface to operate on - * Rect: Requested rectangle - * - * Returns: - * TRUE if the texture part can be loaded, - * FALSE otherwise - * - *********************************************************************/ -BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) -{ - const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; - int x1 = Rect->left, x2 = Rect->right; - int y1 = Rect->top, y2 = Rect->bottom; - GLint maxSize = gl_info->limits.texture_size; - - TRACE("(%p)->(%d,%d)-(%d,%d)\n", This, - Rect->left, Rect->top, Rect->right, Rect->bottom); - - /* The sizes might be reversed */ - if(Rect->left > Rect->right) { - x1 = Rect->right; - x2 = Rect->left; - } - if(Rect->top > Rect->bottom) { - y1 = Rect->bottom; - y2 = Rect->top; - } - - /* No oversized texture? This is easy */ - if(!(This->Flags & SFLAG_OVERSIZE)) { - /* Which rect from the texture do I need? */ - if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB) - { - glTexCoord[0] = (float) Rect->left; - glTexCoord[2] = (float) Rect->top; - glTexCoord[1] = (float) Rect->right; - glTexCoord[3] = (float) Rect->bottom; - } else { - glTexCoord[0] = (float) Rect->left / (float) This->pow2Width; - glTexCoord[2] = (float) Rect->top / (float) This->pow2Height; - glTexCoord[1] = (float) Rect->right / (float) This->pow2Width; - glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height; - } - - return TRUE; - } else { - /* Check if we can succeed at all */ - if( (x2 - x1) > maxSize || - (y2 - y1) > maxSize ) { - TRACE("Requested rectangle is too large for gl\n"); - return FALSE; - } - - /* A part of the texture has to be picked. First, check if - * some texture part is loaded already, if yes try to re-use it. - * If the texture is dirty, or the part can't be used, - * re-position the part to load - */ - if(This->Flags & SFLAG_INTEXTURE) { - if(This->glRect.left <= x1 && This->glRect.right >= x2 && - This->glRect.top <= y1 && This->glRect.bottom >= x2 ) { - /* Ok, the rectangle is ok, re-use it */ - TRACE("Using existing gl Texture\n"); - } else { - /* Rectangle is not ok, dirtify the texture to reload it */ - TRACE("Dirtifying texture to force reload\n"); - This->Flags &= ~SFLAG_INTEXTURE; - } - } - - /* Now if we are dirty(no else if!) */ - if(!(This->Flags & SFLAG_INTEXTURE)) { - /* Set the new rectangle. Use the following strategy: - * 1) Use as big textures as possible. - * 2) Place the texture part in the way that the requested - * part is in the middle of the texture(well, almost) - * 3) If the texture is moved over the edges of the - * surface, replace it nicely - * 4) If the coord is not limiting the texture size, - * use the whole size - */ - if((This->pow2Width) > maxSize) { - This->glRect.left = x1 - maxSize / 2; - if(This->glRect.left < 0) { - This->glRect.left = 0; - } - This->glRect.right = This->glRect.left + maxSize; - if(This->glRect.right > This->currentDesc.Width) { - This->glRect.right = This->currentDesc.Width; - This->glRect.left = This->glRect.right - maxSize; - } - } else { - This->glRect.left = 0; - This->glRect.right = This->pow2Width; - } - - if (This->pow2Height > maxSize) - { - This->glRect.top = x1 - gl_info->limits.texture_size / 2; - if(This->glRect.top < 0) This->glRect.top = 0; - This->glRect.bottom = This->glRect.left + maxSize; - if(This->glRect.bottom > This->currentDesc.Height) { - This->glRect.bottom = This->currentDesc.Height; - This->glRect.top = This->glRect.bottom - maxSize; - } - } else { - This->glRect.top = 0; - This->glRect.bottom = This->pow2Height; - } - TRACE("(%p): Using rect (%d,%d)-(%d,%d)\n", This, - This->glRect.left, This->glRect.top, This->glRect.right, This->glRect.bottom); - } - - /* Re-calculate the rect to draw */ - Rect->left -= This->glRect.left; - Rect->right -= This->glRect.left; - Rect->top -= This->glRect.top; - Rect->bottom -= This->glRect.top; - - /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size, - * or the pow2Width / pow2Height of the surface. - * - * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up - * as regular GL_TEXTURE_2D. - */ - glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left); - glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top); - glTexCoord[1] = (float) Rect->right / (float) (This->glRect.right - This->glRect.left); - glTexCoord[3] = (float) Rect->bottom / (float) (This->glRect.bottom - This->glRect.top); - } - return TRUE; -} - void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) { #define ARG1 0x01 #define ARG2 0x02 @@ -2518,8 +2778,8 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB) { - IWineD3DSurfaceImpl *surf; - surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)stateblock->textures[0]; + IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0]; if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask) { @@ -2826,8 +3086,10 @@ UINT wined3d_log2i(UINT32 x) * and the user preferences in wined3d_settings. */ void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected) { + BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20); + if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE; - else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) + else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl) { /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB @@ -2839,7 +3101,7 @@ void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, else *vs_selected = SHADER_NONE; if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE; - else if (gl_info->supported[ARB_FRAGMENT_SHADER] && wined3d_settings.glslRequested) *ps_selected = SHADER_GLSL; + else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL; else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB; else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI; else *ps_selected = SHADER_NONE; diff --git a/dll/directx/wine/wined3d/view.c b/dll/directx/wine/wined3d/view.c index bbf0f5f65c1..0c9919dd14c 100644 --- a/dll/directx/wine/wined3d/view.c +++ b/dll/directx/wine/wined3d/view.c @@ -97,7 +97,7 @@ static HRESULT STDMETHODCALLTYPE rendertarget_view_GetResource(IWineD3DRendertar return WINED3D_OK; } -const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl = +static const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl = { /* IUnknown methods */ rendertarget_view_QueryInterface, @@ -108,3 +108,13 @@ const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl = /* IWineD3DRendertargetView methods */ rendertarget_view_GetResource, }; + +void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, + IWineD3DResource *resource, IUnknown *parent) +{ + view->vtbl = &wined3d_rendertarget_view_vtbl; + view->refcount = 1; + IWineD3DResource_AddRef(resource); + view->resource = resource; + view->parent = parent; +} diff --git a/dll/directx/wine/wined3d/volume.c b/dll/directx/wine/wined3d/volume.c index 8e19ee9c763..42e61e68d22 100644 --- a/dll/directx/wine/wined3d/volume.c +++ b/dll/directx/wine/wined3d/volume.c @@ -25,7 +25,6 @@ #include "wined3d_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); -#define GLINFO_LOCATION This->resource.device->adapter->gl_info /* Context activation is done by the caller. */ static void volume_bind_and_dirtify(IWineD3DVolume *iface) { @@ -313,9 +312,11 @@ static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWi } /* Context activation is done by the caller. */ -static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) { - IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; - const struct GlPixelFormatDesc *glDesc = This->resource.format_desc; +static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) +{ + IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; + const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; + const struct wined3d_format_desc *glDesc = This->resource.format_desc; TRACE("(%p) : level %u, format %s (0x%08x)\n", This, gl_level, debug_d3dformat(glDesc->format), glDesc->format); @@ -386,7 +387,7 @@ HRESULT volume_init(IWineD3DVolumeImpl *volume, IWineD3DDeviceImpl *device, UINT IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); HRESULT hr; if (!gl_info->supported[EXT_TEXTURE3D]) diff --git a/dll/directx/wine/wined3d/volumetexture.c b/dll/directx/wine/wined3d/volumetexture.c index 14ca72fcd49..9fccb2b8936 100644 --- a/dll/directx/wine/wined3d/volumetexture.c +++ b/dll/directx/wine/wined3d/volumetexture.c @@ -39,7 +39,7 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE TRACE("(%p) : About to load texture.\n", This); - if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); + if (!device->isInDraw) context = context_acquire(device, NULL); else if (gl_info->supported[EXT_TEXTURE_SRGB] && This->baseTexture.bindCount > 0) { srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE]; @@ -51,17 +51,19 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE * since the last load then reload the volumes. */ if (This->baseTexture.texture_rgb.dirty) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode); + IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i]; + IWineD3DVolume_LoadTexture(volume, i, srgb_mode); } } else if (srgb_was_toggled) { - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - volume_add_dirty_box(This->volumes[i], NULL); - IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode); + IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i]; + volume_add_dirty_box(volume, NULL); + IWineD3DVolume_LoadTexture(volume, i, srgb_mode); } } else @@ -81,9 +83,9 @@ static void volumetexture_cleanup(IWineD3DVolumeTextureImpl *This) TRACE("(%p) : Cleaning up.\n", This); - for (i = 0; i < This->baseTexture.levels; ++i) + for (i = 0; i < This->baseTexture.level_count; ++i) { - IWineD3DVolume *volume = This->volumes[i]; + IWineD3DVolume *volume = (IWineD3DVolume *)This->baseTexture.sub_resources[i]; if (volume) { @@ -172,8 +174,9 @@ static void WINAPI IWineD3DVolumeTextureImpl_UnLoad(IWineD3DVolumeTexture *iface * surface before, this one will be a NOP and vice versa. Unloading an unloaded * surface is fine */ - for (i = 0; i < This->baseTexture.levels; i++) { - IWineD3DVolume_UnLoad(This->volumes[i]); + for (i = 0; i < This->baseTexture.level_count; ++i) + { + IWineD3DVolume_UnLoad((IWineD3DVolume *)This->baseTexture.sub_resources[i]); } basetexture_unload((IWineD3DBaseTexture *)iface); @@ -250,65 +253,95 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_IsCondNP2(IWineD3DVolumeTexture *if /* ******************************************* IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow ******************************************* */ -static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, UINT Level,WINED3DVOLUME_DESC *pDesc) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - if (Level < This->baseTexture.levels) { - TRACE("(%p) Level (%d)\n", This, Level); - return IWineD3DVolume_GetDesc(This->volumes[Level], pDesc); - } else { - WARN("(%p) Level (%d)\n", This, Level); +static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, + UINT level, WINED3DVOLUME_DESC *desc) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; + + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } + + return IWineD3DVolume_GetDesc(volume, desc); +} + +static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, + UINT level, IWineD3DVolume **volume) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *v; + + TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); + + if (!(v = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; + } + + IWineD3DVolume_AddRef(v); + *volume = v; + + TRACE("Returning volume %p.\n", *volume); + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, UINT Level, IWineD3DVolume** ppVolumeLevel) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - if (Level < This->baseTexture.levels) { - *ppVolumeLevel = This->volumes[Level]; - IWineD3DVolume_AddRef(*ppVolumeLevel); - TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel); - } else { - WARN("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + +static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, + UINT level, WINED3DLOCKED_BOX *locked_box, const WINED3DBOX *box, DWORD flags) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; + + TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n", + iface, level, locked_box, box, flags); + + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return WINED3D_OK; -} -static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, UINT Level, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) { - HRESULT hr; - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - - if (Level < This->baseTexture.levels) { - hr = IWineD3DVolume_LockBox(This->volumes[Level], pLockedVolume, pBox, Flags); - TRACE("(%p) Level (%d) success(%u)\n", This, Level, hr); - - } else { - FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; - } - return hr; + return IWineD3DVolume_LockBox(volume, locked_box, box, flags); } -static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT Level) { - HRESULT hr; - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; +static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT level) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; - if (Level < This->baseTexture.levels) { - hr = IWineD3DVolume_UnlockBox(This->volumes[Level]); - TRACE("(%p) -> level(%d) success(%u)\n", This, Level, hr); + TRACE("iface %p, level %u.\n", iface, level); - } else { - FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); - return WINED3DERR_INVALIDCALL; + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, level))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; } - return hr; + + return IWineD3DVolume_UnlockBox(volume); } -static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, CONST WINED3DBOX* pDirtyBox) { - IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; - This->baseTexture.texture_rgb.dirty = TRUE; - This->baseTexture.texture_srgb.dirty = TRUE; - TRACE("(%p) : dirtyfication of volume Level (0)\n", This); - volume_add_dirty_box(This->volumes[0], pDirtyBox); +static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, const WINED3DBOX *dirty_box) +{ + IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface; + IWineD3DVolume *volume; + + TRACE("iface %p, dirty_box %p.\n", iface, dirty_box); + + if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, 0, 0))) + { + WARN("Failed to get sub-resource.\n"); + return WINED3DERR_INVALIDCALL; + } + + texture->baseTexture.texture_rgb.dirty = TRUE; + texture->baseTexture.texture_srgb.dirty = TRUE; + volume_add_dirty_box(volume, dirty_box); return WINED3D_OK; } @@ -355,7 +388,7 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); + const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT tmp_w, tmp_h, tmp_d; unsigned int i; HRESULT hr; @@ -399,8 +432,8 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT texture->lpVtbl = &IWineD3DVolumeTexture_Vtbl; - hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels, WINED3DRTYPE_VOLUMETEXTURE, - device, 0, usage, format_desc, pool, parent, parent_ops); + hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, 1, levels, + WINED3DRTYPE_VOLUMETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x.\n", hr); @@ -418,21 +451,23 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT tmp_h = height; tmp_d = depth; - for (i = 0; i < texture->baseTexture.levels; ++i) + for (i = 0; i < texture->baseTexture.level_count; ++i) { + IWineD3DVolume *volume; + /* Create the volume. */ hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent, - tmp_w, tmp_h, tmp_d, format, pool, usage, &texture->volumes[i]); + tmp_w, tmp_h, tmp_d, format, pool, usage, &volume); if (FAILED(hr)) { ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr); - texture->volumes[i] = NULL; volumetexture_cleanup(texture); return hr; } /* Set its container to this texture. */ - IWineD3DVolume_SetContainer(texture->volumes[i], (IWineD3DBase *)texture); + IWineD3DVolume_SetContainer(volume, (IWineD3DBase *)texture); + texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)volume; /* Calculate the next mipmap level. */ tmp_w = max(1, tmp_w >> 1); diff --git a/dll/directx/wine/wined3d/wined3d_gl.h b/dll/directx/wine/wined3d/wined3d_gl.h index f8097d65cb9..4ece7e7df9a 100644 --- a/dll/directx/wine/wined3d/wined3d_gl.h +++ b/dll/directx/wine/wined3d/wined3d_gl.h @@ -1754,6 +1754,7 @@ typedef enum wined3d_gl_extension ARB_SHADER_OBJECTS, ARB_SHADER_TEXTURE_LOD, ARB_SHADING_LANGUAGE_100, + ARB_SHADOW, ARB_SYNC, ARB_TEXTURE_BORDER_CLAMP, ARB_TEXTURE_COMPRESSION, @@ -1782,6 +1783,7 @@ typedef enum wined3d_gl_extension EXT_BLEND_EQUATION_SEPARATE, EXT_BLEND_FUNC_SEPARATE, EXT_BLEND_MINMAX, + EXT_DRAW_BUFFERS2, EXT_FOG_COORD, EXT_FRAMEBUFFER_BLIT, EXT_FRAMEBUFFER_MULTISAMPLE, @@ -1829,7 +1831,6 @@ typedef enum wined3d_gl_extension SGIS_GENERATE_MIPMAP, SGI_VIDEO_SYNC, /* WGL extensions */ - WGL_ARB_PBUFFER, WGL_ARB_PIXEL_FORMAT, WGL_WINE_PIXEL_FORMAT_PASSTHROUGH, /* Internally used */ @@ -2404,6 +2405,14 @@ typedef unsigned int GLhandleARB; #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8b8c #endif +/* GL_ARB_shadow */ +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884c +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884d +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884e +#endif + /* GL_ARB_sync */ #ifndef GL_ARB_sync #define GL_ARB_sync 1 @@ -2959,6 +2968,15 @@ typedef void (WINE_GLAPI *PGLFNBLENDEQUATIONSEPARATEEXTPROC)(GLenum modeRGB, GLe typedef void (WINE_GLAPI *PGLFNBLENDFUNCSEPARATEEXTPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +/* GL_EXT_draw_buffers2 */ +typedef GLvoid (WINE_GLAPI *PGLFNCOLORMASKINDEXEDEXTPROC)(GLuint buffer_idx, GLboolean r, GLboolean g, + GLboolean b, GLboolean a); +typedef GLvoid (WINE_GLAPI *PGLFNGETBOOLEANINDEXEDVEXTPROC)(GLenum param, GLuint index, GLboolean *value); +typedef GLvoid (WINE_GLAPI *PGLFNGETINTEGERINDEXEDVEXTPROC)(GLenum param, GLuint index, GLint *value); +typedef GLvoid (WINE_GLAPI *PGLFNENABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef GLvoid (WINE_GLAPI *PGLFNDISABLEINDEXEDEXTPROC)(GLenum target, GLuint index); +typedef GLboolean (WINE_GLAPI *PGLFNISENABLEDINDEXEDEXTPROC)(GLenum target, GLuint index); + /* GL_EXT_fog_coord */ #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 @@ -3680,26 +3698,6 @@ typedef const char *(WINAPI *WINED3D_PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc); #define WGL_SAMPLES_ARB 0x2042 #endif -/* WGL_ARB_pbuffer */ -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -#define WGL_DRAW_TO_PBUFFER_ARB 0x202d -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202e -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202f -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif -DECLARE_HANDLE(HPBUFFERARB); -typedef HPBUFFERARB (WINAPI *WINED3D_PFNWGLCREATEPBUFFERARBPROC)(HDC hDC, int iPixelFormat, - int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI *WINED3D_PFNWGLGETPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer); -typedef int (WINAPI *WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI *WINED3D_PFNWGLDESTROYPBUFFERARBPROC)(HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI *WINED3D_PFNWGLQUERYPBUFFERARBPROC)(HPBUFFERARB hPbuffer, int iAttribute, int *piValue); - /* WGL_ARB_pixel_format */ #ifndef WGL_ARB_pixel_format #define WGL_ARB_pixel_format 1 @@ -3930,7 +3928,7 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma glUniform3iARB, ARB_SHADER_OBJECTS, NULL) \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM4IARBPROC, \ glUniform4iARB, ARB_SHADER_OBJECTS, NULL) \ - USE_GL_FUNC(WINED3D_PFNGLUNIFORM1IARBPROC, \ + USE_GL_FUNC(WINED3D_PFNGLUNIFORM1FARBPROC, \ glUniform1fARB, ARB_SHADER_OBJECTS, NULL) \ USE_GL_FUNC(WINED3D_PFNGLUNIFORM2FARBPROC, \ glUniform2fARB, ARB_SHADER_OBJECTS, NULL) \ @@ -4199,6 +4197,19 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma /* GL_EXT_blend_func_separate */ \ USE_GL_FUNC(PGLFNBLENDEQUATIONSEPARATEEXTPROC, \ glBlendEquationSeparateEXT, EXT_BLEND_EQUATION_SEPARATE, NULL) \ + /* GL_EXT_draw_buffers2 */ \ + USE_GL_FUNC(PGLFNCOLORMASKINDEXEDEXTPROC, \ + glColorMaskIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNGETBOOLEANINDEXEDVEXTPROC, \ + glGetBooleanIndexedvEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNGETINTEGERINDEXEDVEXTPROC, \ + glGetIntegerIndexedvEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNENABLEINDEXEDEXTPROC, \ + glEnableIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNDISABLEINDEXEDEXTPROC, \ + glDisableIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ + USE_GL_FUNC(PGLFNISENABLEDINDEXEDEXTPROC, \ + glIsEnabledIndexedEXT, EXT_DRAW_BUFFERS2, NULL) \ /* GL_EXT_fog_coord */ \ USE_GL_FUNC(PGLFNGLFOGCOORDFEXTPROC, \ glFogCoordfEXT, EXT_FOG_COORD, NULL) \ @@ -4489,11 +4500,6 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma USE_GL_FUNC(WINED3D_PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB, 0, NULL) \ USE_GL_FUNC(WINED3D_PFNWGLGETPIXELFORMATATTRIBFVARBPROC, wglGetPixelFormatAttribfvARB, 0, NULL) \ USE_GL_FUNC(WINED3D_PFNWGLCHOOSEPIXELFORMATARBPROC, wglChoosePixelFormatARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLCREATEPBUFFERARBPROC, wglCreatePbufferARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLDESTROYPBUFFERARBPROC, wglDestroyPbufferARB, 0, NULL) \ - USE_GL_FUNC(WINED3D_PFNWGLQUERYPBUFFERARBPROC, wglQueryPbufferARB, 0, NULL) \ USE_GL_FUNC(WINED3D_PFNWGLSETPIXELFORMATWINE, wglSetPixelFormatWINE, 0, NULL) #endif /* __WINE_WINED3D_GL */ diff --git a/dll/directx/wine/wined3d/wined3d_main.c b/dll/directx/wine/wined3d/wined3d_main.c index 39416e1f875..6330eba44d4 100644 --- a/dll/directx/wine/wined3d/wined3d_main.c +++ b/dll/directx/wine/wined3d/wined3d_main.c @@ -72,30 +72,31 @@ wined3d_settings_t wined3d_settings = PCI_DEVICE_NONE,/* PCI Device ID */ 0, /* The default of memory is set in FillGLCaps */ NULL, /* No wine logo by default */ - FALSE /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */ + FALSE, /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */ + FALSE, /* No strict draw ordering. */ }; -IWineD3D* WINAPI WineDirect3DCreate(UINT dxVersion, IUnknown *parent) { - IWineD3DImpl* object; +IWineD3D * WINAPI WineDirect3DCreate(UINT version, IUnknown *parent) +{ + IWineD3DImpl *object; + HRESULT hr; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DImpl)); - object->lpVtbl = &IWineD3D_Vtbl; - object->dxVersion = dxVersion; - object->ref = 1; - object->parent = parent; - - if (!InitAdapters(object)) + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) { - WARN("Failed to initialize direct3d adapters, Direct3D will not be available\n"); - if (dxVersion > 7) - { - ERR("Direct3D%d is not available without opengl\n", dxVersion); - HeapFree(GetProcessHeap(), 0, object); - return NULL; - } + ERR("Failed to allocate wined3d object memory.\n"); + return NULL; } - TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion); + hr = wined3d_init(object, version, parent); + if (FAILED(hr)) + { + WARN("Failed to initialize wined3d object, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return NULL; + } + + TRACE("Created wined3d object %p for d3d%d support.\n", object, version); return (IWineD3D *)object; } @@ -120,7 +121,7 @@ static void CDECL wined3d_do_nothing(void) { } -static BOOL wined3d_init(HINSTANCE hInstDLL) +static BOOL wined3d_dll_init(HINSTANCE hInstDLL) { DWORD wined3d_context_tls_idx; HMODULE mod; @@ -236,11 +237,6 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) TRACE("Using the backbuffer for offscreen rendering\n"); wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER; } - else if (!strcmp(buffer,"pbuffer")) - { - TRACE("Using PBuffers for offscreen rendering\n"); - wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER; - } else if (!strcmp(buffer,"fbo")) { TRACE("Using FBOs for offscreen rendering\n"); @@ -324,6 +320,12 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) wined3d_settings.allow_multisampling = TRUE; } } + if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size) + && !strcmp(buffer,"enabled")) + { + TRACE("Enforcing strict draw ordering.\n"); + wined3d_settings.strict_draw_ordering = TRUE; + } } if (wined3d_settings.vs_mode == VS_HW) TRACE("Allow HW vertex shaders\n"); @@ -338,7 +340,7 @@ static BOOL wined3d_init(HINSTANCE hInstDLL) return TRUE; } -static BOOL wined3d_destroy(HINSTANCE hInstDLL) +static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL) { DWORD wined3d_context_tls_idx = context_get_tls_idx(); unsigned int i; @@ -478,10 +480,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) switch (fdwReason) { case DLL_PROCESS_ATTACH: - return wined3d_init(hInstDLL); + return wined3d_dll_init(hInstDLL); case DLL_PROCESS_DETACH: - return wined3d_destroy(hInstDLL); + return wined3d_dll_destroy(hInstDLL); case DLL_THREAD_DETACH: { diff --git a/dll/directx/wine/wined3d/wined3d_private.h b/dll/directx/wine/wined3d/wined3d_private.h index 1d5cd974645..5c96d764389 100644 --- a/dll/directx/wine/wined3d/wined3d_private.h +++ b/dll/directx/wine/wined3d/wined3d_private.h @@ -50,6 +50,7 @@ #define WINED3D_QUIRK_GLSL_CLIP_VARYING 0x00000004 #define WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA 0x00000008 #define WINED3D_QUIRK_NV_CLIP_BROKEN 0x00000010 +#define WINED3D_QUIRK_FBO_TEX_UPDATE 0x00000020 /* Texture format fixups */ @@ -67,10 +68,11 @@ enum fixup_channel_source enum complex_fixup { - COMPLEX_FIXUP_YUY2 = 0, - COMPLEX_FIXUP_UYVY = 1, - COMPLEX_FIXUP_YV12 = 2, - COMPLEX_FIXUP_P8 = 3, + COMPLEX_FIXUP_NONE = 0, + COMPLEX_FIXUP_YUY2 = 1, + COMPLEX_FIXUP_UYVY = 2, + COMPLEX_FIXUP_YV12 = 3, + COMPLEX_FIXUP_P8 = 4, }; #include @@ -234,8 +236,7 @@ static inline float float_24_to_32(DWORD in) #define VBO_HW 1 #define ORM_BACKBUFFER 0 -#define ORM_PBUFFER 1 -#define ORM_FBO 2 +#define ORM_FBO 1 #define SHADER_ARB 1 #define SHADER_GLSL 2 @@ -267,6 +268,7 @@ typedef struct wined3d_settings_s { unsigned int emulated_textureram; char *logo; int allow_multisampling; + BOOL strict_draw_ordering; } wined3d_settings_t; extern wined3d_settings_t wined3d_settings DECLSPEC_HIDDEN; @@ -539,7 +541,8 @@ typedef struct shader_reg_maps WORD usestexldl : 1; WORD usesifc : 1; WORD usescall : 1; - WORD padding : 4; + WORD usesrcp : 1; + WORD padding : 3; /* Whether or not loops are used in this shader, and nesting depth */ unsigned loop_depth; @@ -643,14 +646,6 @@ struct shader_caps { float PixelShader1xMaxValue; DWORD MaxPixelShaderConst; - WINED3DVSHADERCAPS2_0 VS20Caps; - WINED3DPSHADERCAPS2_0 PS20Caps; - - DWORD MaxVShaderInstructionsExecuted; - DWORD MaxPShaderInstructionsExecuted; - DWORD MaxVertexShader30InstructionSlots; - DWORD MaxPixelShader30InstructionSlots; - BOOL VSClipping; }; @@ -693,6 +688,7 @@ struct ps_compile_args { /* Bitmap for NP2 texcoord fixups (16 samplers max currently). D3D9 has a limit of 16 samplers and the fixup is superfluous in D3D10 (unconditional NP2 support mandatory). */ + WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */ }; enum fog_src_type { @@ -711,7 +707,7 @@ struct wined3d_context; typedef struct { void (*shader_handle_instruction)(const struct wined3d_shader_instruction *); void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS); - void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type); + void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type, const SIZE *ds_mask_size); void (*shader_deselect_depth_blt)(IWineD3DDevice *iface); void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count); void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count); @@ -752,7 +748,7 @@ extern int num_lock DECLSPEC_HIDDEN; /* GL related defines */ /* ------------------ */ -#define GL_EXTCALL(FuncName) (GLINFO_LOCATION.FuncName) +#define GL_EXTCALL(f) (gl_info->f) #define D3DCOLOR_B_R(dw) (((dw) >> 16) & 0xFF) #define D3DCOLOR_B_G(dw) (((dw) >> 8) & 0xFF) @@ -771,9 +767,6 @@ extern int num_lock DECLSPEC_HIDDEN; (vec)[3] = D3DCOLOR_A(dw); \ } while(0) -/* DirectX Device Limits */ -/* --------------------- */ -#define MAX_MIP_LEVELS 32 /* Maximum number of mipmap levels. */ #define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */ /* Checking of API calls */ @@ -788,7 +781,7 @@ do { \ TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__); \ \ } else do { \ - FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \ + ERR(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \ debug_glerror(err), err, A, __FILE__, __LINE__); \ err = glGetError(); \ } while (err != GL_NO_ERROR); \ @@ -830,13 +823,6 @@ extern const float identity[16] DECLSPEC_HIDDEN; * Compilable extra diagnostics */ -/* Trace information per-vertex: (extremely high amount of trace) */ -#if 0 /* NOTE: Must be 0 in cvs */ -# define VTRACE(A) TRACE A -#else -# define VTRACE(A) -#endif - /* TODO: Confirm each of these works when wined3d move completed */ #if 0 /* NOTE: Must be 0 in cvs */ /* To avoid having to get gigabytes of trace, the following can be compiled in, and at the start @@ -910,7 +896,7 @@ enum wined3d_ffp_emit_idx struct wined3d_stream_info_element { - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; GLsizei stride; const BYTE *data; UINT stream_idx; @@ -1039,6 +1025,12 @@ enum wined3d_event_query_result WINED3D_EVENT_QUERY_ERROR }; +void wined3d_event_query_destroy(struct wined3d_event_query *query) DECLSPEC_HIDDEN; +enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +HRESULT wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; + struct wined3d_context { const struct wined3d_gl_info *gl_info; @@ -1052,8 +1044,8 @@ struct wined3d_context DWORD numDirtyEntries; DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ - IWineD3DSurface *surface; - IWineD3DSurface *current_rt; + IWineD3DSwapChainImpl *swapchain; + IWineD3DSurfaceImpl *current_rt; DWORD tid; /* Thread ID which owns this context at the moment */ /* Stores some information about the context state for optimization */ @@ -1089,7 +1081,7 @@ struct wined3d_context HGLRC glCtx; HWND win_handle; HDC hdc; - HPBUFFERARB pbuffer; + int pixel_format; GLint aux_buffers; /* FBOs */ @@ -1097,10 +1089,11 @@ struct wined3d_context struct list fbo_list; struct list fbo_destroy_list; struct fbo_entry *current_fbo; - GLuint src_fbo; GLuint dst_fbo; GLuint fbo_read_binding; GLuint fbo_draw_binding; + BOOL rebind_fbo; + IWineD3DSurfaceImpl **blit_targets; /* Queries */ GLuint *free_occlusion_queries; @@ -1167,60 +1160,69 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_ const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex, const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN; +enum blit_operation +{ + BLIT_OP_BLIT, + BLIT_OP_COLOR_FILL +}; + /* Shaders for color conversions in blits */ struct blit_shader { HRESULT (*alloc_private)(IWineD3DDevice *iface); void (*free_private)(IWineD3DDevice *iface); - HRESULT (*set_shader)(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc, - GLenum textype, UINT width, UINT height); + HRESULT (*set_shader)(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface); void (*unset_shader)(IWineD3DDevice *iface); - BOOL (*color_fixup_supported)(struct color_fixup_desc fixup); + BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op, + const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format_desc *src_format_desc, + const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format_desc *dst_format_desc); + HRESULT (*color_fill)(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color); }; extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN; extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN; +extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN; -typedef enum ContextUsage { - CTXUSAGE_RESOURCELOAD = 1, /* Only loads textures: No State is applied */ - CTXUSAGE_DRAWPRIM = 2, /* OpenGL states are set up for blitting DirectDraw surfaces */ - CTXUSAGE_BLIT = 3, /* OpenGL states are set up 3D drawing */ - CTXUSAGE_CLEAR = 4, /* Drawable and states are set up for clearing */ -} ContextUsage; +/* Temporary blit_shader helper functions */ +HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op, + DWORD Filter) DECLSPEC_HIDDEN; -struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, - IWineD3DSurface *target, enum ContextUsage usage) DECLSPEC_HIDDEN; +struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target) DECLSPEC_HIDDEN; void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query) DECLSPEC_HIDDEN; void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; -void context_resource_released(IWineD3DDevice *iface, - IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN; -void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo) DECLSPEC_HIDDEN; +void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; +void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; +void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void context_attach_depth_stencil_fbo(struct wined3d_context *context, - GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN; -void context_attach_surface_fbo(const struct wined3d_context *context, - GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) DECLSPEC_HIDDEN; -struct wined3d_context *context_create(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, - BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *present_parameters) DECLSPEC_HIDDEN; + GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN; +void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo) DECLSPEC_HIDDEN; +struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target, + const struct wined3d_format_desc *ds_format_desc) DECLSPEC_HIDDEN; void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) DECLSPEC_HIDDEN; void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN; void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN; DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN; void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN; +void context_resource_released(IWineD3DDevice *iface, + IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN; BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN; void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN; void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN; - -void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN; -HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain) DECLSPEC_HIDDEN; +void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; /* Macros for doing basic GPU detection based on opengl capabilities */ #define WINE_D3D6_CAPABLE(gl_info) (gl_info->supported[ARB_MULTITEXTURE]) #define WINE_D3D7_CAPABLE(gl_info) (gl_info->supported[ARB_TEXTURE_COMPRESSION] && gl_info->supported[ARB_TEXTURE_CUBE_MAP] && gl_info->supported[ARB_TEXTURE_ENV_DOT3]) #define WINE_D3D8_CAPABLE(gl_info) WINE_D3D7_CAPABLE(gl_info) && (gl_info->supported[ARB_MULTISAMPLE] && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP]) #define WINE_D3D9_CAPABLE(gl_info) WINE_D3D8_CAPABLE(gl_info) && (gl_info->supported[ARB_FRAGMENT_PROGRAM] && gl_info->supported[ARB_VERTEX_SHADER]) +#define WINE_D3D10_CAPABLE(gl_info) WINE_D3D9_CAPABLE(gl_info) && (gl_info->supported[EXT_GPU_SHADER4]) /***************************************************************************** * Internal representation of a light @@ -1251,7 +1253,6 @@ typedef struct WineD3D_PixelFormat int redSize, greenSize, blueSize, alphaSize, colorSize; int depthSize, stencilSize; BOOL windowDrawable; - BOOL pbufferDrawable; BOOL doubleBuffer; int auxBuffers; int numSamples; @@ -1259,9 +1260,9 @@ typedef struct WineD3D_PixelFormat enum wined3d_gl_vendor { - GL_VENDOR_WINE, + GL_VENDOR_UNKNOWN, GL_VENDOR_APPLE, - GL_VENDOR_ATI, + GL_VENDOR_FGLRX, GL_VENDOR_INTEL, GL_VENDOR_MESA, GL_VENDOR_NVIDIA, @@ -1270,7 +1271,7 @@ enum wined3d_gl_vendor enum wined3d_pci_vendor { - HW_VENDOR_WINE = 0x0000, + HW_VENDOR_SOFTWARE = 0x0000, HW_VENDOR_ATI = 0x1002, HW_VENDOR_NVIDIA = 0x10de, HW_VENDOR_INTEL = 0x8086, @@ -1287,7 +1288,7 @@ enum wined3d_pci_device CARD_ATI_RADEON_XPRESS_200M = 0x5955, CARD_ATI_RADEON_X700 = 0x5e4c, CARD_ATI_RADEON_X1600 = 0x71c2, - CARD_ATI_RADEON_HD2300 = 0x7210, + CARD_ATI_RADEON_HD2350 = 0x94c7, CARD_ATI_RADEON_HD2600 = 0x9581, CARD_ATI_RADEON_HD2900 = 0x9400, CARD_ATI_RADEON_HD3200 = 0x9620, @@ -1418,6 +1419,7 @@ struct wined3d_gl_limits struct wined3d_gl_info { + DWORD glsl_version; UINT vidmem; struct wined3d_gl_limits limits; DWORD reserved_glsl_constants; @@ -1433,7 +1435,7 @@ struct wined3d_gl_info WGL_EXT_FUNCS_GEN #undef USE_GL_FUNC - struct GlPixelFormatDesc *gl_formats; + struct wined3d_format_desc *gl_formats; }; struct wined3d_driver_info @@ -1469,7 +1471,7 @@ struct wined3d_adapter BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) DECLSPEC_HIDDEN; BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram) DECLSPEC_HIDDEN; +extern unsigned int WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, unsigned int glram) DECLSPEC_HIDDEN; extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; /***************************************************************************** @@ -1564,14 +1566,9 @@ typedef struct IWineD3DImpl struct wined3d_adapter adapters[1]; } IWineD3DImpl; -extern const IWineD3DVtbl IWineD3D_Vtbl DECLSPEC_HIDDEN; - +HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent) DECLSPEC_HIDDEN; BOOL wined3d_register_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN; -BOOL InitAdapters(IWineD3DImpl *This) DECLSPEC_HIDDEN; - -/* A helper function that dumps a resource list */ -void dumpResources(struct list *list) DECLSPEC_HIDDEN; /***************************************************************************** * IWineD3DDevice implementation structure @@ -1656,9 +1653,10 @@ struct IWineD3DDeviceImpl unsigned int highest_dirty_ps_const, highest_dirty_vs_const; /* Render Target Support */ - IWineD3DSurface **render_targets; - IWineD3DSurface *auto_depth_stencil_buffer; - IWineD3DSurface *stencilBufferTarget; + IWineD3DSurfaceImpl **render_targets; + IWineD3DSurfaceImpl *auto_depth_stencil; + IWineD3DSurfaceImpl *onscreen_depth_stencil; + IWineD3DSurfaceImpl *depth_stencil; /* palettes texture management */ UINT NumberOfPalettes; @@ -1701,12 +1699,12 @@ struct IWineD3DDeviceImpl /* Stream source management */ struct wined3d_stream_info strided_streams; const WineDirect3DVertexStridedData *up_strided; + struct wined3d_event_query *buffer_queries[MAX_ATTRIBS]; + unsigned int num_buffer_queries; /* Context management */ struct wined3d_context **contexts; UINT numContexts; - struct wined3d_context *pbufferContext; /* The context that has a pbuffer as drawable */ - DWORD pbufferWidth, pbufferHeight; /* Size of the buffer drawable */ /* High level patch management */ #define PATCHMAP_SIZE 43 @@ -1715,6 +1713,9 @@ struct IWineD3DDeviceImpl struct WineD3DRectPatch *currentPatch; }; +BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN; HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d, UINT adapter_idx, WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags, IUnknown *parent, IWineD3DDeviceParent *device_parent) DECLSPEC_HIDDEN; @@ -1725,6 +1726,8 @@ void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource) D void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource) DECLSPEC_HIDDEN; void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) DECLSPEC_HIDDEN; +void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, struct wined3d_context *context, + IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN; @@ -1770,7 +1773,7 @@ typedef struct IWineD3DResourceClass WINED3DPOOL pool; UINT size; DWORD usage; - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; DWORD priority; BYTE *allocatedMemory; /* Pointer to the real data location */ BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */ @@ -1793,7 +1796,7 @@ DWORD resource_get_priority(IWineD3DResource *iface) DECLSPEC_HIDDEN; HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid, void *data, DWORD *data_size) DECLSPEC_HIDDEN; HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, + IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface) DECLSPEC_HIDDEN; DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority) DECLSPEC_HIDDEN; @@ -1801,7 +1804,7 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, const void *data, DWORD data_size, DWORD flags) DECLSPEC_HIDDEN; /* Tests show that the start address of resources is 32 byte aligned */ -#define RESOURCE_ALIGNMENT 32 +#define RESOURCE_ALIGNMENT 16 /***************************************************************************** * IWineD3DBaseTexture D3D- > openGL state map lookups @@ -1818,10 +1821,8 @@ typedef enum winetexturestates { WINED3DTEXSTA_MAXMIPLEVEL = 7, WINED3DTEXSTA_MAXANISOTROPY = 8, WINED3DTEXSTA_SRGBTEXTURE = 9, - WINED3DTEXSTA_ELEMENTINDEX = 10, - WINED3DTEXSTA_DMAPOFFSET = 11, - WINED3DTEXSTA_TSSADDRESSW = 12, - MAX_WINETEXTURESTATES = 13, + WINED3DTEXSTA_SHADOW = 10, + MAX_WINETEXTURESTATES = 11, } winetexturestates; enum WINED3DSRGB @@ -1845,7 +1846,9 @@ struct gl_texture typedef struct IWineD3DBaseTextureClass { struct gl_texture texture_rgb, texture_srgb; - UINT levels; + IWineD3DResourceImpl **sub_resources; + UINT layer_count; + UINT level_count; float pow2Matrix[16]; UINT LOD; WINED3DTEXTUREFILTERTYPE filterType; @@ -1858,10 +1861,11 @@ typedef struct IWineD3DBaseTextureClass void (*internal_preload)(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb); } IWineD3DBaseTextureClass; -void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; -BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN; -BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN; -void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) DECLSPEC_HIDDEN; +void surface_internal_preload(IWineD3DSurfaceImpl *surface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; +BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; +BOOL surface_is_offscreen(IWineD3DSurfaceImpl *iface) DECLSPEC_HIDDEN; +void surface_prepare_texture(IWineD3DSurfaceImpl *surface, + const struct wined3d_gl_info *gl_info, BOOL srgb) DECLSPEC_HIDDEN; typedef struct IWineD3DBaseTextureImpl { @@ -1883,9 +1887,12 @@ WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN; DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN; DWORD basetexture_get_lod(IWineD3DBaseTexture *iface) DECLSPEC_HIDDEN; -HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type, - IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc, - WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, + UINT layer, UINT level) DECLSPEC_HIDDEN; +HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count, + WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage, + const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent, + const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type) DECLSPEC_HIDDEN; BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty) DECLSPEC_HIDDEN; @@ -1903,7 +1910,6 @@ typedef struct IWineD3DTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DTexture */ - IWineD3DSurface *surfaces[MAX_MIP_LEVELS]; UINT target; BOOL cond_np2; @@ -1922,9 +1928,6 @@ typedef struct IWineD3DCubeTextureImpl const IWineD3DCubeTextureVtbl *lpVtbl; IWineD3DResourceClass resource; IWineD3DBaseTextureClass baseTexture; - - /* IWineD3DCubeTexture */ - IWineD3DSurface *surfaces[6][MAX_MIP_LEVELS]; } IWineD3DCubeTextureImpl; HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels, @@ -1971,9 +1974,6 @@ typedef struct IWineD3DVolumeTextureImpl const IWineD3DVolumeTextureVtbl *lpVtbl; IWineD3DResourceClass resource; IWineD3DBaseTextureClass baseTexture; - - /* IWineD3DVolumeTexture */ - IWineD3DVolume *volumes[MAX_MIP_LEVELS]; } IWineD3DVolumeTextureImpl; HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT height, @@ -2009,8 +2009,8 @@ typedef struct { struct fbo_entry { struct list entry; - IWineD3DSurface **render_targets; - IWineD3DSurface *depth_stencil; + IWineD3DSurfaceImpl **render_targets; + IWineD3DSurfaceImpl *depth_stencil; BOOL attached; GLuint id; }; @@ -2052,9 +2052,6 @@ struct IWineD3DSurfaceImpl /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */ void (*get_drawable_size)(struct wined3d_context *context, UINT *width, UINT *height); - /* Oversized texture */ - RECT glRect; - /* PBO */ GLuint pbo; GLuint texture_name; @@ -2082,6 +2079,7 @@ struct IWineD3DSurfaceImpl struct list renderbuffers; renderbuffer_entry_t *current_renderbuffer; + SIZE ds_current_size; /* DirectDraw clippers */ IWineD3DClipper *clipper; @@ -2097,13 +2095,14 @@ struct IWineD3DSurfaceImpl extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl DECLSPEC_HIDDEN; extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl DECLSPEC_HIDDEN; -UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, +UINT surface_calculate_size(const struct wined3d_format_desc *format_desc, UINT alignment, UINT width, UINT height) DECLSPEC_HIDDEN; void surface_gdi_cleanup(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN; HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment, UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type, UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; +void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; /* Predeclare the shared Surface functions */ HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, @@ -2153,13 +2152,13 @@ const void *WINAPI IWineD3DBaseSurfaceImpl_GetData(IWineD3DSurface *iface) DECLS void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; -void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; +void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) DECLSPEC_HIDDEN; void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPEC_HIDDEN; /* Surface flags: */ -#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */ #define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */ #define SFLAG_DIBSECTION 0x00000004 /* Has a DIB section attached for GetDC */ #define SFLAG_LOCKABLE 0x00000008 /* Surface can be locked */ @@ -2186,7 +2185,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE #define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */ /* In some conditions the surface memory must not be freed: - * SFLAG_OVERSIZE: Not all data can be kept in GL * SFLAG_CONVERTED: Converting the data back would take too long * SFLAG_DIBSECTION: The dib code manages the memory * SFLAG_LOCKED: The app requires access to the surface data @@ -2194,8 +2192,7 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL. * SFLAG_CLIENT: OpenGL uses our memory as backup */ -#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \ - SFLAG_CONVERTED | \ +#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \ SFLAG_DIBSECTION | \ SFLAG_LOCKED | \ SFLAG_DYNLOCK | \ @@ -2212,38 +2209,19 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPE SFLAG_DS_OFFSCREEN) #define SFLAG_DS_DISCARDED SFLAG_DS_LOCATIONS -BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]) DECLSPEC_HIDDEN; - typedef enum { NO_CONVERSION, CONVERT_PALETTED, CONVERT_PALETTED_CK, CONVERT_CK_565, CONVERT_CK_5551, - CONVERT_CK_4444, - CONVERT_CK_4444_ARGB, - CONVERT_CK_1555, - CONVERT_555, CONVERT_CK_RGB24, - CONVERT_CK_8888, - CONVERT_CK_8888_ARGB, - CONVERT_RGB32_888, - CONVERT_V8U8, - CONVERT_L6V5U5, - CONVERT_X8L8V8U8, - CONVERT_Q8W8V8U8, - CONVERT_V16U16, - CONVERT_A4L4, - CONVERT_G16R16, - CONVERT_R16G16F, - CONVERT_R32G32F, - CONVERT_D15S1, - CONVERT_D24X4S4, - CONVERT_D24FS8, + CONVERT_RGB32_888 } CONVERT_TYPES; -HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, - GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) DECLSPEC_HIDDEN; +HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, + struct wined3d_format_desc *desc, CONVERT_TYPES *convert) DECLSPEC_HIDDEN; +void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) DECLSPEC_HIDDEN; BOOL palette9_changed(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN; @@ -2253,7 +2231,7 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) DECLSPEC_HIDDEN; struct wined3d_vertex_declaration_element { - const struct GlPixelFormatDesc *format_desc; + const struct wined3d_format_desc *format_desc; BOOL ffp_valid; WORD input_slot; WORD offset; @@ -2432,6 +2410,14 @@ HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device, WINED3DSTATEBLOCKTYPE type) DECLSPEC_HIDDEN; void stateblock_init_contained_states(IWineD3DStateBlockImpl *object) DECLSPEC_HIDDEN; +static inline void stateblock_apply_state(DWORD state, IWineD3DStateBlockImpl *stateblock, + struct wined3d_context *context) +{ + const struct StateEntry *statetable = stateblock->device->StateTable; + DWORD rep = statetable[state].representative; + statetable[rep].apply(rep, stateblock, context); +} + /* Direct3D terminology with little modifications. We do not have an issued state * because only the driver knows about it, but we have a created state because d3d * allows GetData on a created issue, but opengl doesn't @@ -2485,6 +2471,9 @@ struct wined3d_map_range #define WINED3D_BUFFER_CREATEBO 0x04 /* Attempt to create a buffer object next PreLoad */ #define WINED3D_BUFFER_DOUBLEBUFFER 0x08 /* Use a vbo and local allocated memory */ #define WINED3D_BUFFER_FLUSH 0x10 /* Manual unmap flushing */ +#define WINED3D_BUFFER_DISCARD 0x20 /* A DISCARD lock has occurred since the last PreLoad */ +#define WINED3D_BUFFER_NOSYNC 0x40 /* All locks since the last PreLoad had NOOVERWRITE set */ +#define WINED3D_BUFFER_APPLESYNC 0x80 /* Using sync as in GL_APPLE_flush_buffer_range */ struct wined3d_buffer { @@ -2503,6 +2492,7 @@ struct wined3d_buffer LONG lock_count; struct wined3d_map_range *maps; ULONG maps_size, modified_areas; + struct wined3d_event_query *query; /* conversion stuff */ UINT decl_change_count, full_conversion_count; @@ -2514,8 +2504,9 @@ struct wined3d_buffer UINT *conversion_shift; /* NULL if no shifted conversion */ }; -const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) DECLSPEC_HIDDEN; -BYTE *buffer_get_sysmem(struct wined3d_buffer *This) DECLSPEC_HIDDEN; +const BYTE *buffer_get_memory(IWineD3DBuffer *iface, const struct wined3d_gl_info *gl_info, + GLuint *buffer_object) DECLSPEC_HIDDEN; +BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; @@ -2530,7 +2521,8 @@ struct wined3d_rendertarget_view IUnknown *parent; }; -extern const IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl DECLSPEC_HIDDEN; +void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view, + IWineD3DResource *resource, IUnknown *parent) DECLSPEC_HIDDEN; /***************************************************************************** * IWineD3DSwapChainImpl implementation structure (extends IUnknown) @@ -2546,21 +2538,23 @@ struct IWineD3DSwapChainImpl IWineD3DDeviceImpl *device; /* IWineD3DSwapChain fields */ - IWineD3DSurface **backBuffer; - IWineD3DSurface *frontBuffer; + IWineD3DSurfaceImpl **back_buffers; + IWineD3DSurfaceImpl *front_buffer; WINED3DPRESENT_PARAMETERS presentParms; DWORD orig_width, orig_height; WINED3DFORMAT orig_fmt; WINED3DGAMMARAMP orig_gamma; BOOL render_to_fbo; + const struct wined3d_format_desc *ds_format; - long prev_time, frames; /* Performance tracking */ + LONG prev_time, frames; /* Performance tracking */ unsigned int vSyncCounter; struct wined3d_context **context; unsigned int num_contexts; HWND win_handle; + HWND device_window; }; const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN; @@ -2580,7 +2574,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *ifac HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE *pMode) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, - IWineD3DDevice **ppDevice) DECLSPEC_HIDDEN; + IWineD3DDevice **device) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) DECLSPEC_HIDDEN; HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, @@ -2624,6 +2618,9 @@ const char *debug_d3dtop(WINED3DTEXTUREOP d3dtop) DECLSPEC_HIDDEN; void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN; const char *debug_surflocation(DWORD flag) DECLSPEC_HIDDEN; +/* Color conversion routines */ +DWORD color_convert_argb_to_fmt(DWORD color, WINED3DFORMAT destfmt) DECLSPEC_HIDDEN; + /* Routines for GL <-> D3D values */ GLenum StencilOp(DWORD op) DECLSPEC_HIDDEN; GLenum CompareFunc(DWORD func) DECLSPEC_HIDDEN; @@ -2650,18 +2647,19 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) DECLSPEC_HIDDEN; -void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect) DECLSPEC_HIDDEN; -GLenum surface_get_gl_buffer(IWineD3DSurface *iface) DECLSPEC_HIDDEN; -void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) DECLSPEC_HIDDEN; -void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, +void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) DECLSPEC_HIDDEN; +GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN; +void surface_load_ds_location(IWineD3DSurfaceImpl *surface, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +void surface_modify_ds_location(IWineD3DSurfaceImpl *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; +void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height) DECLSPEC_HIDDEN; -void surface_set_texture_name(IWineD3DSurface *iface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; -void surface_set_texture_target(IWineD3DSurface *iface, GLenum target) DECLSPEC_HIDDEN; +void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; +void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) DECLSPEC_HIDDEN; -BOOL getColorBits(const struct GlPixelFormatDesc *format_desc, +BOOL getColorBits(const struct wined3d_format_desc *format_desc, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize) DECLSPEC_HIDDEN; -BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, +BOOL getDepthStencilBits(const struct wined3d_format_desc *format_desc, short *depthSize, short *stencilSize) DECLSPEC_HIDDEN; /* Math utils */ @@ -2941,8 +2939,8 @@ struct IWineD3DPaletteImpl { DWORD Flags; }; -extern const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl DECLSPEC_HIDDEN; -DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) DECLSPEC_HIDDEN; +HRESULT wined3d_palette_init(IWineD3DPaletteImpl *palette, IWineD3DDeviceImpl *device, + DWORD flags, const PALETTEENTRY *entries, IUnknown *parent) DECLSPEC_HIDDEN; /* DirectDraw utility functions */ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN; @@ -2952,17 +2950,23 @@ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN; */ /* WineD3D pixel format flags */ -#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1 -#define WINED3DFMT_FLAG_FILTERING 0x2 -#define WINED3DFMT_FLAG_DEPTH 0x4 -#define WINED3DFMT_FLAG_STENCIL 0x8 -#define WINED3DFMT_FLAG_RENDERTARGET 0x10 -#define WINED3DFMT_FLAG_FOURCC 0x20 -#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x40 -#define WINED3DFMT_FLAG_COMPRESSED 0x80 -#define WINED3DFMT_FLAG_GETDC 0x100 +#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x00000001 +#define WINED3DFMT_FLAG_FILTERING 0x00000002 +#define WINED3DFMT_FLAG_DEPTH 0x00000004 +#define WINED3DFMT_FLAG_STENCIL 0x00000008 +#define WINED3DFMT_FLAG_RENDERTARGET 0x00000010 +#define WINED3DFMT_FLAG_FOURCC 0x00000020 +#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040 +#define WINED3DFMT_FLAG_COMPRESSED 0x00000080 +#define WINED3DFMT_FLAG_GETDC 0x00000100 +#define WINED3DFMT_FLAG_FLOAT 0x00000200 +#define WINED3DFMT_FLAG_BUMPMAP 0x00000400 +#define WINED3DFMT_FLAG_SRGB_READ 0x00000800 +#define WINED3DFMT_FLAG_SRGB_WRITE 0x00001000 +#define WINED3DFMT_FLAG_VTF 0x00002000 +#define WINED3DFMT_FLAG_SHADOW 0x00004000 -struct GlPixelFormatDesc +struct wined3d_format_desc { WINED3DFORMAT format; DWORD red_mask; @@ -2989,12 +2993,14 @@ struct GlPixelFormatDesc GLint rtInternal; GLint glFormat; GLint glType; + UINT conv_byte_count; unsigned int Flags; float heightscale; struct color_fixup_desc color_fixup; + void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height); }; -const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, +const struct wined3d_format_desc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock) @@ -3013,9 +3019,9 @@ static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock) return (stateblock->pixelShader && stateblock->device->ps_selected_mode != SHADER_NONE); } -void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, - WINED3DRECT *src_rect, IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, - const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) DECLSPEC_HIDDEN; +void stretch_rect_fbo(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, + const RECT *src_rect, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, + const WINED3DTEXTUREFILTERTYPE filter) DECLSPEC_HIDDEN; /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */ #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL" @@ -3024,4 +3030,6 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff)) + #endif diff --git a/dll/keyboard/kbdlv/kbdlv.c b/dll/keyboard/kbdlv/kbdlv.c index d2befa16a2e..a9954371b5d 100644 --- a/dll/keyboard/kbdlv/kbdlv.c +++ b/dll/keyboard/kbdlv/kbdlv.c @@ -1,7 +1,7 @@ /* - * ReactOS Latvian Keyboard layout + * ReactOS latvian Keyboard layout * Copyright (C) 2008 ReactOS - * Author: Dmitry Chapyshev + * Author: Dmitry Chapyshev, Arthurs B. * License: LGPL, see: LGPL.txt * * Thanks to: http://www.barcodeman.com/altek/mule/scandoc.php @@ -33,8 +33,6 @@ #define KNUMS 0xc00 /* Special + number pad */ #define KMEXT 0x300 /* Multi + ext */ -#define SHFT_INVALID 0x0F - ROSDATA USHORT scancode_to_vk[] = { /* Numbers Row */ /* - 00 - */ @@ -60,10 +58,10 @@ ROSDATA USHORT scancode_to_vk[] = { /* Third letters row */ 'Z', 'X', 'C', 'V', 'B', 'N', 'M', VK_OEM_COMMA, - VK_OEM_PERIOD,VK_OEM_2, VK_RSHIFT | KEXT, + VK_OEM_PERIOD,VK_OEM_2, VK_RSHIFT, /* - 37 - */ /* Bottom Row */ - 0x26a, VK_LMENU, VK_SPACE, VK_CAPITAL, + VK_MULTIPLY, VK_LMENU, VK_SPACE, VK_CAPITAL, /* - 3b - */ /* F-Keys */ @@ -86,8 +84,8 @@ ROSDATA USHORT scancode_to_vk[] = { /* Oddities, and the remaining standard F-Keys */ VK_EMPTY, VK_OEM_102, VK_F11, VK_F12, /* - 59 - */ - VK_CLEAR, VK_OEM_WSCTRL,VK_OEM_FINISH,VK_OEM_JUMP, VK_EREOF, /* EREOF */ - VK_OEM_BACKTAB, VK_OEM_AUTO, VK_EMPTY, VK_ZOOM, /* ZOOM */ + VK_CLEAR, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* EREOF */ + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* ZOOM */ VK_HELP, /* - 64 - */ /* Even more F-Keys (for example, NCR keyboards from the early 90's) */ @@ -95,64 +93,25 @@ ROSDATA USHORT scancode_to_vk[] = { VK_F21, VK_F22, VK_F23, /* - 6f - */ /* Not sure who uses these codes */ - VK_OEM_PA3, VK_EMPTY, VK_OEM_RESET, + VK_EMPTY, VK_EMPTY, VK_EMPTY, /* - 72 - */ - VK_EMPTY, 0xc1, VK_EMPTY, VK_EMPTY, + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* - 76 - */ /* One more f-key */ VK_F24, /* - 77 - */ VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, - VK_OEM_PA1, VK_TAB, 0xc2, 0, /* PA1 */ - 0, + VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* PA1 */ + VK_EMPTY, /* - 80 - */ 0 }; ROSDATA VSC_VK extcode0_to_vk[] = { - { 0x10, VK_MEDIA_PREV_TRACK | KEXT }, - { 0x19, VK_MEDIA_NEXT_TRACK | KEXT }, - { 0x1D, VK_RCONTROL | KEXT }, - { 0x20, VK_VOLUME_MUTE | KEXT }, - { 0x21, VK_LAUNCH_APP2 | KEXT }, - { 0x22, VK_MEDIA_PLAY_PAUSE | KEXT }, - { 0x24, VK_MEDIA_STOP | KEXT }, - { 0x2E, VK_VOLUME_DOWN | KEXT }, - { 0x30, VK_VOLUME_UP | KEXT }, - { 0x32, VK_BROWSER_HOME | KEXT }, - { 0x35, VK_DIVIDE | KEXT }, - { 0x37, VK_SNAPSHOT | KEXT }, - { 0x38, VK_RMENU | KEXT }, - { 0x47, VK_HOME | KEXT }, - { 0x48, VK_UP | KEXT }, - { 0x49, VK_PRIOR | KEXT }, - { 0x4B, VK_LEFT | KEXT }, - { 0x4D, VK_RIGHT | KEXT }, - { 0x4F, VK_END | KEXT }, - { 0x50, VK_DOWN | KEXT }, - { 0x51, VK_NEXT | KEXT }, - { 0x52, VK_INSERT | KEXT }, - { 0x53, VK_DELETE | KEXT }, - { 0x5B, VK_LWIN | KEXT }, - { 0x5C, VK_RWIN | KEXT }, - { 0x5D, VK_APPS | KEXT }, - { 0x5F, VK_SLEEP | KEXT }, - { 0x65, VK_BROWSER_SEARCH | KEXT }, - { 0x66, VK_BROWSER_FAVORITES | KEXT }, - { 0x67, VK_BROWSER_REFRESH | KEXT }, - { 0x68, VK_BROWSER_STOP | KEXT }, - { 0x69, VK_BROWSER_FORWARD | KEXT }, - { 0x6A, VK_BROWSER_BACK | KEXT }, - { 0x6B, VK_LAUNCH_APP1 | KEXT }, - { 0x6C, VK_LAUNCH_MAIL | KEXT }, - { 0x6D, VK_LAUNCH_MEDIA_SELECT | KEXT }, - { 0x1C, VK_RETURN | KEXT }, - { 0x46, VK_CANCEL | KEXT }, { 0, 0 }, }; ROSDATA VSC_VK extcode1_to_vk[] = { - { 0x1d, VK_PAUSE}, { 0, 0 }, }; @@ -165,91 +124,93 @@ ROSDATA VK_TO_BIT modifier_keys[] = { ROSDATA MODIFIERS modifier_bits = { modifier_keys, - 7, - { 0, 1, 4, 5, SHFT_INVALID, SHFT_INVALID, 2, 3 } + 3, + { 0, 1, 2, 3 } /* Modifier bit order, NONE, SHIFT, CTRL, ALT */ }; #define NOCAPS 0 #define CAPS KSHIFT /* Caps -> shift */ ROSDATA VK_TO_WCHARS2 key_to_chars_2mod[] = { - { VK_OEM_3, NOCAPS, {0x00ad, '?' } }, - { '9', NOCAPS, {'9', '(' } }, - { '0', NOCAPS, {'0', ')' } }, - { 'J', CAPS, {'j', 'J' } }, - { 'N', CAPS, {'n', 'N' } }, - { 'Z', CAPS, {'z', 'Z' } }, - { 'W', CAPS, {0x0113, 0x0112} }, - { 'X', CAPS, {0x010d, 0x010c} }, - { VK_OEM_1, CAPS, {0x0161, 0x0160} }, - { 'U', CAPS, {'u', 'U' } }, - { 'S', CAPS, {'s', 'S' } }, - { 'I', CAPS, {'i', 'I' } }, - { 'L', CAPS, {'l', 'L' } }, - { 'D', CAPS, {'d', 'D' } }, - { 'A', CAPS, {'a', 'A' } }, - { 'T', CAPS, {'t', 'T' } }, - { 'C', CAPS, {'c', 'C' } }, - { 'P', CAPS, {'p', 'P' } }, - { VK_OEM_8, CAPS, {0x0101, 0x0100} }, - { VK_OEM_2, CAPS, {0x013c, 0x013b} }, - { VK_DECIMAL, NOCAPS, {',', ',' } }, - { VK_TAB, NOCAPS, {'\t', '\t' } }, - { VK_ADD, NOCAPS, {'+', '+' } }, - { VK_DIVIDE, NOCAPS, {'/', '/' } }, - { VK_MULTIPLY, NOCAPS, {'*', '*' } }, - { VK_SUBTRACT, NOCAPS, {'-', '-' } }, + /* Normal vs Shifted */ + /* The numbers */ + { '1', NOCAPS, {'1', '!'} }, + /* Ctrl-2 generates NUL */ + { '3', NOCAPS, {'3', '#'} }, + { '4', NOCAPS, {'4', '$'} }, + { '5', NOCAPS, {'5', '%'} }, + /* Ctrl-6 generates RS */ + { '7', NOCAPS, {'7', '&'} }, + { '8', NOCAPS, {'8', '*'} }, + { '9', NOCAPS, {'9', '('} }, + { '0', NOCAPS, {'0', ')'} }, + + /* Specials */ + /* Ctrl-_ generates US */ + { VK_OEM_PLUS ,NOCAPS, {'=', '+'} }, + { VK_OEM_1 ,NOCAPS, {';', ':'} }, + { VK_OEM_7 ,NOCAPS, {'\'','\"'} }, + { VK_OEM_3 ,NOCAPS, {'`', '~'} }, + { VK_OEM_COMMA ,NOCAPS, {',', '<'} }, + { VK_OEM_PERIOD ,NOCAPS, {'.', '>'} }, + { VK_OEM_2 ,NOCAPS, {'/', '?'} }, + /* Keys that do not have shift states */ + { VK_TAB ,NOCAPS, {'\t','\t'} }, + { VK_ADD ,NOCAPS, {'+', '+'} }, + { VK_SUBTRACT,NOCAPS, {'-', '-'} }, + { VK_MULTIPLY,NOCAPS, {'*', '*'} }, + { VK_DIVIDE ,NOCAPS, {'/', '/'} }, + { VK_ESCAPE ,NOCAPS, {'\x1b','\x1b'} }, + { VK_SPACE ,NOCAPS, {' ', ' '} }, { 0, 0 } }; ROSDATA VK_TO_WCHARS3 key_to_chars_3mod[] = { - { '1', NOCAPS, {'1', '!', 0x00ab} }, - { '8', NOCAPS, {'8', 0x00d7, ':' } }, - { 'E', CAPS, {'e', 'E', 0x20ac} }, - { VK_OEM_COMMA, NOCAPS, {',', ';', '<' } }, - { VK_OEM_PERIOD, NOCAPS, {'.', ':', '>' } }, - { 0, 0 } + /* Normal, Shifted, Ctrl */ + /* Legacy (telnet-style) ascii escapes */ + { VK_OEM_4, 0, {'[', '{', 0x1b /* ESC */} }, + { VK_OEM_6, 0, {']', '}', 0x1d /* GS */} }, + { VK_OEM_5, 0, {'\\','|', 0x1c /* FS */} }, + { VK_OEM_102,0,{'\\','|', 0x1c /* FS */} }, + { VK_RETURN,0, {'\r', '\r', '\n'} }, + { 0,0 } }; ROSDATA VK_TO_WCHARS4 key_to_chars_4mod[] = { - { '2', NOCAPS, {'2', 0x00ab, WCH_NONE, '@' } }, - { '3', NOCAPS, {'3', 0x00bb, WCH_NONE, '#' } }, - { '4', NOCAPS, {'4', '$', 0x20ac, '$' } }, - { '5', NOCAPS, {'5', '%', '\"', WCH_DEAD} }, - { 0xff, NOCAPS, {WCH_NONE, WCH_NONE, WCH_NONE, '~' } }, - { '7', NOCAPS, {'7', '&', WCH_NONE, 0x00b1 } }, - { 'F', CAPS, {'f', 'F', '=', ';' } }, - { 'Q', CAPS, {0x016b, 0x016a, 'q', 'Q' } }, - { 'G', CAPS, {'g', 'G', 0x0123, 0x0122 } }, - { 'R', CAPS, {'r', 'R', 0x0157, 0x0156 } }, - { 'M', CAPS, {'m', 'M', 'w', 'W' } }, - { 'V', CAPS, {'v', 'V', 'y', 'Y' } }, - { 'Y', CAPS, {0x017e, 0x017d, '[', '{' } }, - { 'H', CAPS, {'h', 'H', ']', '}' } }, - { VK_OEM_7, NOCAPS, {WCH_DEAD, WCH_DEAD, WCH_DEAD, WCH_DEAD} }, - { 0xff, NOCAPS, {0x00b4, 0x00b0, 0x00b4, 0x00a8 } }, - { 'B', CAPS, {'b', 'B', 'x', 'X' } }, - { 'K', CAPS, {'k', 'K', 0x0137, 0x0136 } }, - { 'O', CAPS, {'o', 'O', 0x00f5, 0x00d5 } }, - { 0, 0 } -}; + /* Normal, Shifted, Ctrl, C-S-x */ -ROSDATA VK_TO_WCHARS5 key_to_chars_5mod[] = { - { VK_OEM_5, CAPS, {0x0137, 0x0136, WCH_NONE, WCH_NONE, 0x001c} }, - { VK_OEM_4, CAPS, {0x0146, 0x0145, WCH_NONE, WCH_NONE, 0x001b} }, - { VK_OEM_6, CAPS, {0x012b, 0x012a, WCH_NONE, WCH_NONE, 0x001d} }, - { VK_OEM_102, CAPS, {0x0123, 0x0122, '\\', '|', 0x001c} }, - { VK_BACK, NOCAPS, {'\b', '\b', WCH_NONE, WCH_NONE, 0x007f} }, - { VK_ESCAPE, NOCAPS, {0x001b, 0x001b, WCH_NONE, WCH_NONE, 0x001b} }, - { VK_RETURN, NOCAPS, {'\r', '\r', WCH_NONE, WCH_NONE, '\n' } }, - { VK_SPACE, NOCAPS, {' ', ' ', WCH_NONE, WCH_NONE, ' ' } }, - { VK_CANCEL, NOCAPS, {0x0003, 0x0003, WCH_NONE, WCH_NONE, 0x0003} }, - { 0, 0 } -}; + /* The alphabet */ + { 'A', CAPS, {'a', 'A', 0x101, 0x100} }, + { 'B', CAPS, {'b', 'B', 0x02, 0x02} }, + { 'C', CAPS, {'c', 'C', 0x10d, 0x10c} }, + { 'D', CAPS, {'d', 'D', 0x04, 0x04} }, + { 'E', CAPS, {'e', 'E', 0x113, 0x112} }, + { 'F', CAPS, {'f', 'F', 0x06, 0x06} }, + { 'G', CAPS, {'g', 'G', 0x123, 0x122} }, + { 'H', CAPS, {'h', 'H', 0x08, 0x08} }, + { 'I', CAPS, {'i', 'I', 0x12b, 0x12a} }, + { 'J', CAPS, {'j', 'J', 0x0a, 0x0a} }, + { 'K', CAPS, {'k', 'K', 0x137, 0x136} }, + { 'L', CAPS, {'l', 'L', 0x13c, 0x13b} }, + { 'M', CAPS, {'m', 'M', 0x0d, 0x0d} }, + { 'N', CAPS, {'n', 'N', 0x146, 0x145} }, + { 'O', CAPS, {'o', 'O', 0x0f, 0x0f} }, + { 'P', CAPS, {'p', 'P', 0x10, 0x10} }, + { 'Q', CAPS, {'q', 'Q', 0x11, 0x11} }, + { 'R', CAPS, {'r', 'R', 0x12, 0x12} }, + { 'S', CAPS, {'s', 'S', 0x161, 0x160} }, + { 'T', CAPS, {'t', 'T', 0x14, 0x14} }, + { 'U', CAPS, {'u', 'U', 0x16b, 0x16a} }, + { 'V', CAPS, {'v', 'V', 0x16, 0x16} }, + { 'W', CAPS, {'w', 'W', 0x17, 0x17} }, + { 'X', CAPS, {'x', 'X', 0x18, 0x18} }, + { 'Y', CAPS, {'y', 'Y', 0x19, 0x19} }, + { 'Z', CAPS, {'z', 'Z', 0x17e, 0x17d} }, -ROSDATA VK_TO_WCHARS6 key_to_chars_6mod[] = { - { '6', NOCAPS, {'6', '/', 0x2019, '^', WCH_NONE, 0x001e} }, - { VK_OEM_MINUS, NOCAPS, {'-', '_', 0x2013, 0x2014, WCH_NONE, 0x001f} }, + /* Legacy Ascii generators */ + { '2', NOCAPS, {'2', '@', WCH_NONE, 0} }, + { '6', NOCAPS, {'6', '^', WCH_NONE, 0x1e /* RS */} }, + { VK_OEM_MINUS, NOCAPS, {'-', '_', WCH_NONE, 0x1f /* US */} }, { 0, 0 } }; @@ -264,22 +225,23 @@ ROSDATA VK_TO_WCHARS1 keypad_numbers[] = { { VK_NUMPAD7, 0, {'7'} }, { VK_NUMPAD8, 0, {'8'} }, { VK_NUMPAD9, 0, {'9'} }, - { 0, 0 } + { VK_DECIMAL, 0, {'.'} }, + { VK_BACK, 0, {'\010'} }, + { 0,0 } }; #define vk_master(n,x) { (PVK_TO_WCHARS1)x, n, sizeof(x[0]) } ROSDATA VK_TO_WCHAR_TABLE vk_to_wchar_master_table[] = { + vk_master(1,keypad_numbers), + vk_master(2,key_to_chars_2mod), vk_master(3,key_to_chars_3mod), vk_master(4,key_to_chars_4mod), - vk_master(5,key_to_chars_5mod), - vk_master(6,key_to_chars_6mod), - vk_master(2,key_to_chars_2mod), - vk_master(1,keypad_numbers), { 0,0,0 } }; ROSDATA VSC_LPWSTR key_names[] = { + { 0x00, L"" }, { 0x01, L"Esc" }, { 0x0e, L"Backspace" }, { 0x0f, L"Tab" }, @@ -331,12 +293,12 @@ ROSDATA VSC_LPWSTR key_names[] = { { 0x85, L"F22" }, { 0x86, L"F23" }, { 0x87, L"F24" }, - { 0, NULL } + { 0, NULL }, }; ROSDATA VSC_LPWSTR extended_key_names[] = { { 0x1c, L"Num Enter" }, - { 0x1d, L"Right Control" }, + { 0x1d, L"Right Ctrl" }, { 0x35, L"Num /" }, { 0x37, L"Prnt Scrn" }, { 0x38, L"Right Alt" }, @@ -345,7 +307,8 @@ ROSDATA VSC_LPWSTR extended_key_names[] = { { 0x47, L"Home" }, { 0x48, L"Up" }, { 0x49, L"Page Up" }, - { 0x4b, L"Left" }, + { 0x4a, L"Left" }, + { 0x4c, L"Center" }, { 0x4d, L"Right" }, { 0x4f, L"End" }, { 0x50, L"Down" }, @@ -353,60 +316,10 @@ ROSDATA VSC_LPWSTR extended_key_names[] = { { 0x52, L"Insert" }, { 0x53, L"Delete" }, { 0x54, L"" }, - { 0x56, L"Help" }, - { 0x5b, L"Left " }, - { 0x5c, L"Right " }, - { 0x5d, L"Application" }, - { 0, NULL } -}; - -ROSDATA DEADKEY_LPWSTR dead_key_names[] = { - L"\x00b4" L"ACUTE", - L"\x00a8" L"DIAERESIS", - L"\x00b0" L"RING", - L"~" L"TILDE", - NULL -}; - -#define DEADTRANS(ch, accent, comp, flags) MAKELONG(ch, accent), comp, flags - -ROSDATA DEADKEY dead_key[] = { - { DEADTRANS(L'n', 0x00b4, 0x0144, 0x0000) }, - { DEADTRANS(L'c', 0x00b4, 0x0107, 0x0000) }, - { DEADTRANS(L'o', 0x00b4, 0x00f3, 0x0000) }, - { DEADTRANS(L'e', 0x00b4, 0x00e9, 0x0000) }, - { DEADTRANS(L's', 0x00b4, 0x015b, 0x0000) }, - { DEADTRANS(L'z', 0x00b4, 0x017a, 0x0000) }, - { DEADTRANS(L'N', 0x00b4, 0x0143, 0x0000) }, - { DEADTRANS(L'C', 0x00b4, 0x0106, 0x0000) }, - { DEADTRANS(L'O', 0x00b4, 0x00d3, 0x0000) }, - { DEADTRANS(L'E', 0x00b4, 0x00c9, 0x0000) }, - { DEADTRANS(L'S', 0x00b4, 0x015a, 0x0000) }, - { DEADTRANS(L'Z', 0x00b4, 0x0179, 0x0000) }, - { DEADTRANS(L' ', 0x00b4, 0x00b4, 0x0000) }, - - { DEADTRANS(L'a', 0x00a8, 0x00e4, 0x0000) }, - { DEADTRANS(L'u', 0x00a8, 0x00fc, 0x0000) }, - { DEADTRANS(L'o', 0x00a8, 0x00f6, 0x0000) }, - { DEADTRANS(L'A', 0x00a8, 0x00c4, 0x0000) }, - { DEADTRANS(L'U', 0x00a8, 0x00dc, 0x0000) }, - { DEADTRANS(L'O', 0x00a8, 0x00d6, 0x0000) }, - { DEADTRANS(L' ', 0x00a8, 0x00a8, 0x0000) }, - - { DEADTRANS(L'a', 0x00b0, 0x00e5, 0x0000) }, - { DEADTRANS(L'A', 0x00b0, 0x00c5, 0x0000) }, - { DEADTRANS(L'e', 0x00b0, 0x0117, 0x0000) }, - { DEADTRANS(L'E', 0x00b0, 0x0116, 0x0000) }, - { DEADTRANS(L'z', 0x00b0, 0x017c, 0x0000) }, - { DEADTRANS(L'Z', 0x00b0, 0x017b, 0x0000) }, - { DEADTRANS(L'g', 0x00b0, 0x0121, 0x0000) }, - { DEADTRANS(L' ', 0x00b0, 0x00b0, 0x0000) }, - - { DEADTRANS(L'o', L'~', 0x00f5, 0x0000) }, - { DEADTRANS(L'O', L'~', 0x00d5, 0x0000) }, - { DEADTRANS(L' ', L'~', L'~', 0x0000) }, - - {0, 0} + { 0x55, L"Help" }, + { 0x56, L"Left Windows" }, + { 0x5b, L"Right Windows" }, + { 0, NULL }, }; /* Finally, the master table */ @@ -417,13 +330,13 @@ ROSDATA KBDTABLES keyboard_layout_table = { /* character from vk tables */ vk_to_wchar_master_table, - /* diacritical marks */ - dead_key, + /* diacritical marks -- currently implemented by wine code */ + NULL, /* Key names */ (VSC_LPWSTR *)key_names, (VSC_LPWSTR *)extended_key_names, - dead_key_names, /* Dead key names */ + NULL, /* Dead key names */ /* scan code to virtual key maps */ scancode_to_vk, @@ -431,9 +344,9 @@ ROSDATA KBDTABLES keyboard_layout_table = { extcode0_to_vk, extcode1_to_vk, - MAKELONG(1,1), /* Version 1.0 */ + MAKELONG(0,1), /* Version 1.0 */ - /* Ligatures */ + /* Ligatures -- Latvian doesn't have any */ 0, 0, NULL @@ -443,12 +356,3 @@ PKBDTABLES WINAPI KbdLayerDescriptor(VOID) { return &keyboard_layout_table; } -INT WINAPI -DllMain( - PVOID hinstDll, - ULONG dwReason, - PVOID reserved) -{ - return 1; -} - diff --git a/dll/shellext/slayer/lang/cs-CZ.rc b/dll/shellext/slayer/lang/cs-CZ.rc index 063bad46de8..13eed0328fe 100644 --- a/dll/shellext/slayer/lang/cs-CZ.rc +++ b/dll/shellext/slayer/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/shellext/slayer/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2008-07-27 + * UPDATED: 2010-05-25 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -32,7 +32,7 @@ BEGIN PUSHBUTTON "&Upravit...", IDC_EDIT, 162,24,60,14, WS_DISABLED PUSHBUTTON "S&mazat", IDC_DELETE, 162,42,60,14, WS_DISABLED PUSHBUTTON "&OK", IDOK, 95,116,60,14 - PUSHBUTTON "&Storno", IDCANCEL, 162,116,60,14 + PUSHBUTTON "Storno", IDCANCEL, 162,116,60,14 END STRINGTABLE diff --git a/dll/win32/avifil32/avifil32.rbuild b/dll/win32/avifil32/avifil32.rbuild index 1741f2a481d..da4f495711d 100644 --- a/dll/win32/avifil32/avifil32.rbuild +++ b/dll/win32/avifil32/avifil32.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/dll/win32/browseui/internettoolbar.cpp b/dll/win32/browseui/internettoolbar.cpp index c4f6bd004af..bfad8a5bd9c 100644 --- a/dll/win32/browseui/internettoolbar.cpp +++ b/dll/win32/browseui/internettoolbar.cpp @@ -414,10 +414,16 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WP { SMINFO *infoPtr = (SMINFO *)lParam; if ((infoPtr->dwMask & SMIM_FLAGS) != 0) + { if (psmd->uId == FCIDM_MENU_FAVORITES) + { infoPtr->dwFlags |= SMIF_DROPCASCADE; - else{ - infoPtr->dwFlags |= SMIF_TRACKPOPUP;} + } + else + { + infoPtr->dwFlags |= SMIF_TRACKPOPUP; + } + } if ((infoPtr->dwMask & SMIM_ICON) != 0) infoPtr->iIcon = -1; } @@ -1213,7 +1219,7 @@ LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO CComPtr objectWithSite; CComPtr contextMenu; CMINVOKECOMMANDINFO commandInfo; - char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}"; + const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}"; HRESULT hResult; // TODO: Query shell if this command is enabled first diff --git a/dll/win32/browseui/shellbrowser.cpp b/dll/win32/browseui/shellbrowser.cpp index 3a27a1137d8..50e00d656cb 100644 --- a/dll/win32/browseui/shellbrowser.cpp +++ b/dll/win32/browseui/shellbrowser.cpp @@ -282,7 +282,7 @@ void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar) LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { - LRESULT result; + long int result; HRESULT hResult; result = 0; diff --git a/dll/win32/comctl32/comctl32.rbuild b/dll/win32/comctl32/comctl32.rbuild index 3cc1ce2c0ad..150241f9440 100644 --- a/dll/win32/comctl32/comctl32.rbuild +++ b/dll/win32/comctl32/comctl32.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/dll/win32/comctl32/listview.c b/dll/win32/comctl32/listview.c index 1c0f58bbd69..4e13577b48f 100644 --- a/dll/win32/comctl32/listview.c +++ b/dll/win32/comctl32/listview.c @@ -7,6 +7,7 @@ * Copyright 2001 CodeWeavers Inc. * Copyright 2002 Dimitrie O. Paun * Copyright 2009 Nikolay Sivov + * Copyright 2009 Owen Rudge for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -73,7 +74,6 @@ * * States * -- LVIS_ACTIVATING (not currently supported by comctl32.dll version 6.0) - * -- LVIS_CUT * -- LVIS_DROPHILITED * -- LVIS_OVERLAYMASK * @@ -98,9 +98,7 @@ * -- LVN_BEGINSCROLL, LVN_ENDSCROLL * -- LVN_GETINFOTIP * -- LVN_HOTTRACK - * -- LVN_MARQUEEBEGIN * -- LVN_SETDISPINFO - * -- NM_HOVER * -- LVN_BEGINRDRAG * * Messages: @@ -170,9 +168,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(listview); -/* make sure you set this to 0 for production use! */ -#define DEBUG_RANGES 1 - typedef struct tagCOLUMN_INFO { RECT rcHeader; /* tracks the header's rectangle */ @@ -237,81 +232,120 @@ typedef struct tagDELAYED_ITEM_EDIT typedef struct tagLISTVIEW_INFO { + /* control window */ HWND hwndSelf; - HBRUSH hBkBrush; - COLORREF clrBk; - COLORREF clrText; - COLORREF clrTextBk; - HIMAGELIST himlNormal; - HIMAGELIST himlSmall; - HIMAGELIST himlState; - BOOL bLButtonDown; - BOOL bRButtonDown; - BOOL bDragging; - POINT ptClickPos; /* point where the user clicked */ - BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */ - INT nItemHeight; - INT nItemWidth; - RANGES selectionRanges; - INT nSelectionMark; - INT nHotItem; - SHORT notifyFormat; - HWND hwndNotify; RECT rcList; /* This rectangle is really the window * client rectangle possibly reduced by the * horizontal scroll bar and/or header - see * LISTVIEW_UpdateSize. This rectangle offset * by the LISTVIEW_GetOrigin value is in * client coordinates */ - SIZE iconSize; - SIZE iconSpacing; - SIZE iconStateSize; - UINT uCallbackMask; - HWND hwndHeader; - HCURSOR hHotCursor; - HFONT hDefaultFont; - HFONT hFont; - INT ntmHeight; /* Some cached metrics of the font used */ - INT ntmMaxCharWidth; /* by the listview to draw items */ - INT nEllipsisWidth; - BOOL bRedraw; /* Turns on/off repaints & invalidations */ - BOOL bAutoarrange; /* Autoarrange flag when NOT in LVS_AUTOARRANGE */ - BOOL bFocus; + + /* notification window */ + SHORT notifyFormat; + HWND hwndNotify; BOOL bDoChangeNotify; /* send change notification messages? */ - INT nFocusedItem; - RECT rcFocus; - DWORD dwStyle; /* the cached window GWL_STYLE */ - DWORD dwLvExStyle; /* extended listview style */ - DWORD uView; /* current view available through LVM_[G,S]ETVIEW */ + UINT uCallbackMask; + + /* tooltips */ + HWND hwndToolTip; + + /* items */ INT nItemCount; /* the number of items in the list */ HDPA hdpaItems; /* array ITEM_INFO pointers */ HDPA hdpaItemIds; /* array of ITEM_ID pointers */ HDPA hdpaPosX; /* maintains the (X, Y) coordinates of the */ HDPA hdpaPosY; /* items in LVS_ICON, and LVS_SMALLICON modes */ + RANGES selectionRanges; + INT nSelectionMark; /* item to start next multiselection from */ + INT nHotItem; + BOOL bAutoarrange; /* Autoarrange flag when NOT in LVS_AUTOARRANGE */ + + /* columns */ HDPA hdpaColumns; /* array of COLUMN_INFO pointers */ BOOL colRectsDirty; /* trigger column rectangles requery from header */ - POINT currIconPos; /* this is the position next icon will be placed */ - PFNLVCOMPARE pfnCompare; + + /* item metrics */ + BOOL bNoItemMetrics; /* flags if item metrics are not yet computed */ + INT nItemHeight; + INT nItemWidth; + + /* sorting */ + PFNLVCOMPARE pfnCompare; /* sorting callback pointer */ LPARAM lParamSort; + + /* style */ + DWORD dwStyle; /* the cached window GWL_STYLE */ + DWORD dwLvExStyle; /* extended listview style */ + DWORD uView; /* current view available through LVM_[G,S]ETVIEW */ + + /* edit item */ HWND hwndEdit; WNDPROC EditWndProc; INT nEditLabelItem; - INT nLButtonDownItem; /* tracks item to reset multiselection on WM_LBUTTONUP */ + DELAYED_ITEM_EDIT itemEdit; /* Pointer to this structure will be the timer ID */ + + /* icons */ + HIMAGELIST himlNormal; + HIMAGELIST himlSmall; + HIMAGELIST himlState; + SIZE iconSize; + SIZE iconSpacing; + SIZE iconStateSize; + POINT currIconPos; /* this is the position next icon will be placed */ + + /* header */ + HWND hwndHeader; + INT xTrackLine; /* The x coefficient of the track line or -1 if none */ + + /* marquee selection */ + BOOL bMarqueeSelect; /* marquee selection/highlight underway */ + BOOL bScrolling; + RECT marqueeRect; /* absolute coordinates of marquee selection */ + RECT marqueeDrawRect; /* relative coordinates for drawing marquee */ + POINT marqueeOrigin; /* absolute coordinates of marquee click origin */ + + /* focus drawing */ + BOOL bFocus; /* control has focus */ + INT nFocusedItem; + RECT rcFocus; /* focus bounds */ + + /* colors */ + HBRUSH hBkBrush; + COLORREF clrBk; + COLORREF clrText; + COLORREF clrTextBk; + + /* font */ + HFONT hDefaultFont; + HFONT hFont; + INT ntmHeight; /* Some cached metrics of the font used */ + INT ntmMaxCharWidth; /* by the listview to draw items */ + INT nEllipsisWidth; + + /* mouse operation */ + BOOL bLButtonDown; + BOOL bRButtonDown; + BOOL bDragging; + POINT ptClickPos; /* point where the user clicked */ + INT nLButtonDownItem; /* tracks item to reset multiselection on WM_LBUTTONUP */ DWORD dwHoverTime; - HWND hwndToolTip; - - DWORD cditemmode; /* Keep the custom draw flags for an item/row */ + HCURSOR hHotCursor; + /* keyboard operation */ DWORD lastKeyPressTimestamp; WPARAM charCode; INT nSearchParamLength; WCHAR szSearchParam[ MAX_PATH ]; - BOOL bIsDrawing; - INT nMeasureItemHeight; - INT xTrackLine; /* The x coefficient of the track line or -1 if none */ - DELAYED_ITEM_EDIT itemEdit; /* Pointer to this structure will be the timer ID */ - DWORD iVersion; /* CCM_[G,S]ETVERSION */ + /* painting */ + DWORD cditemmode; /* Keep the custom draw flags for an item/row */ + BOOL bIsDrawing; /* Drawing in progress */ + INT nMeasureItemHeight; /* WM_MEASUREITEM result */ + BOOL bRedraw; /* WM_SETREDRAW switch */ + + /* misc */ + DWORD iVersion; /* CCM_[G,S]ETVERSION */ } LISTVIEW_INFO; /* @@ -414,7 +448,6 @@ static void LISTVIEW_GetItemBox(const LISTVIEW_INFO *, INT, LPRECT); static void LISTVIEW_GetItemOrigin(const LISTVIEW_INFO *, INT, LPPOINT); static BOOL LISTVIEW_GetItemPosition(const LISTVIEW_INFO *, INT, LPPOINT); static BOOL LISTVIEW_GetItemRect(const LISTVIEW_INFO *, INT, LPRECT); -static INT LISTVIEW_GetLabelWidth(const LISTVIEW_INFO *, INT); static void LISTVIEW_GetOrigin(const LISTVIEW_INFO *, LPPOINT); static BOOL LISTVIEW_GetViewRect(const LISTVIEW_INFO *, LPRECT); static void LISTVIEW_UpdateSize(LISTVIEW_INFO *); @@ -426,10 +459,10 @@ static BOOL LISTVIEW_SetItemState(LISTVIEW_INFO *, INT, const LVITEMW *); static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *, INT, INT, HWND); static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *, INT, INT, HWND); static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *, INT, BOOL); -static HWND CreateEditLabelT(LISTVIEW_INFO *, LPCWSTR, DWORD, BOOL); static HIMAGELIST LISTVIEW_SetImageList(LISTVIEW_INFO *, INT, HIMAGELIST); static INT LISTVIEW_HitTest(const LISTVIEW_INFO *, LPLVHITTESTINFO, BOOL, BOOL); static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *, BOOL, BOOL); +static BOOL LISTVIEW_Scroll(LISTVIEW_INFO *, INT, INT); /******** Text handling functions *************************************/ @@ -716,25 +749,37 @@ static int get_ansi_notification(UINT unicodeNotificationCode) { switch (unicodeNotificationCode) { + case LVN_BEGINLABELEDITA: case LVN_BEGINLABELEDITW: return LVN_BEGINLABELEDITA; + case LVN_ENDLABELEDITA: case LVN_ENDLABELEDITW: return LVN_ENDLABELEDITA; + case LVN_GETDISPINFOA: case LVN_GETDISPINFOW: return LVN_GETDISPINFOA; + case LVN_SETDISPINFOA: case LVN_SETDISPINFOW: return LVN_SETDISPINFOA; + case LVN_ODFINDITEMA: case LVN_ODFINDITEMW: return LVN_ODFINDITEMA; + case LVN_GETINFOTIPA: case LVN_GETINFOTIPW: return LVN_GETINFOTIPA; /* header forwards */ + case HDN_TRACKA: case HDN_TRACKW: return HDN_TRACKA; + case HDN_ENDTRACKA: case HDN_ENDTRACKW: return HDN_ENDTRACKA; case HDN_BEGINDRAG: return HDN_BEGINDRAG; case HDN_ENDDRAG: return HDN_ENDDRAG; + case HDN_ITEMCHANGINGA: case HDN_ITEMCHANGINGW: return HDN_ITEMCHANGINGA; + case HDN_ITEMCHANGEDA: case HDN_ITEMCHANGEDW: return HDN_ITEMCHANGEDA; + case HDN_ITEMCLICKA: case HDN_ITEMCLICKW: return HDN_ITEMCLICKA; + case HDN_DIVIDERDBLCLICKA: case HDN_DIVIDERDBLCLICKW: return HDN_DIVIDERDBLCLICKA; + default: break; } - ERR("unknown notification %x\n", unicodeNotificationCode); - assert(FALSE); - return 0; + FIXME("unknown notification %x\n", unicodeNotificationCode); + return unicodeNotificationCode; } /* forwards header notifications to listview parent */ @@ -748,12 +793,12 @@ static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, const NMHEADE /* on unicode format exit earlier */ if (infoPtr->notifyFormat == NFR_UNICODE) - return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, - (WPARAM)lpnmh->hdr.idFrom, (LPARAM)lpnmh); + return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, lpnmh->hdr.idFrom, + (LPARAM)lpnmh); /* header always supplies unicode notifications, all we have to do is to convert strings to ANSI */ - nmhA = *(NMHEADERA*)lpnmh; + nmhA = *(const NMHEADERA*)lpnmh; if (lpnmh->pitem) { hditema = *(HDITEMA*)lpnmh->pitem; @@ -778,8 +823,8 @@ static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, const NMHEADE } nmhA.hdr.code = get_ansi_notification(lpnmh->hdr.code); - ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, - (WPARAM)nmhA.hdr.idFrom, (LPARAM)&nmhA); + ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmhA.hdr.idFrom, + (LPARAM)&nmhA); /* cleanup */ Free(text); @@ -1266,20 +1311,17 @@ static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges) } /*** - * Creates an iterator over the items which intersect lprc. + * Creates an iterator over the items which intersect frame. + * Uses absolute coordinates rather than compensating for the current offset. */ -static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *lprc) +static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *frame) { - RECT frame = *lprc, rcItem, rcTemp; - POINT Origin; + RECT rcItem, rcTemp; /* in case we fail, we want to return an empty iterator */ if (!iterator_empty(i)) return FALSE; - LISTVIEW_GetOrigin(infoPtr, &Origin); - - TRACE("(lprc=%s)\n", wine_dbgstr_rect(lprc)); - OffsetRect(&frame, -Origin.x, -Origin.y); + TRACE("(frame=%s)\n", wine_dbgstr_rect(frame)); if (infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON) { @@ -1288,7 +1330,7 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons if (infoPtr->uView == LV_VIEW_ICON && infoPtr->nFocusedItem != -1) { LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcItem); - if (IntersectRect(&rcTemp, &rcItem, lprc)) + if (IntersectRect(&rcTemp, &rcItem, frame)) i->nSpecial = infoPtr->nFocusedItem; } if (!(iterator_rangesitems(i, ranges_create(50)))) return FALSE; @@ -1300,7 +1342,7 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons rcItem.top = (LONG_PTR)DPA_GetPtr(infoPtr->hdpaPosY, nItem); rcItem.right = rcItem.left + infoPtr->nItemWidth; rcItem.bottom = rcItem.top + infoPtr->nItemHeight; - if (IntersectRect(&rcTemp, &rcItem, &frame)) + if (IntersectRect(&rcTemp, &rcItem, frame)) ranges_additem(i->ranges, nItem); } return TRUE; @@ -1309,11 +1351,11 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons { RANGE range; - if (frame.left >= infoPtr->nItemWidth) return TRUE; - if (frame.top >= infoPtr->nItemHeight * infoPtr->nItemCount) return TRUE; + if (frame->left >= infoPtr->nItemWidth) return TRUE; + if (frame->top >= infoPtr->nItemHeight * infoPtr->nItemCount) return TRUE; - range.lower = max(frame.top / infoPtr->nItemHeight, 0); - range.upper = min((frame.bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1; + range.lower = max(frame->top / infoPtr->nItemHeight, 0); + range.upper = min((frame->bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1; if (range.upper <= range.lower) return TRUE; if (!iterator_rangeitems(i, range)) return FALSE; TRACE(" report=%s\n", debugrange(&i->range)); @@ -1321,8 +1363,8 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons else { INT nPerCol = max((infoPtr->rcList.bottom - infoPtr->rcList.top) / infoPtr->nItemHeight, 1); - INT nFirstRow = max(frame.top / infoPtr->nItemHeight, 0); - INT nLastRow = min((frame.bottom - 1) / infoPtr->nItemHeight, nPerCol - 1); + INT nFirstRow = max(frame->top / infoPtr->nItemHeight, 0); + INT nLastRow = min((frame->bottom - 1) / infoPtr->nItemHeight, nPerCol - 1); INT nFirstCol; INT nLastCol; INT lower; @@ -1331,13 +1373,13 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons if (infoPtr->nItemWidth) { - nFirstCol = max(frame.left / infoPtr->nItemWidth, 0); - nLastCol = min((frame.right - 1) / infoPtr->nItemWidth, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); + nFirstCol = max(frame->left / infoPtr->nItemWidth, 0); + nLastCol = min((frame->right - 1) / infoPtr->nItemWidth, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); } else { - nFirstCol = max(frame.left, 0); - nLastCol = min(frame.right - 1, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); + nFirstCol = max(frame->left, 0); + nLastCol = min(frame->right - 1, (infoPtr->nItemCount + nPerCol - 1) / nPerCol); } lower = nFirstCol * nPerCol + nFirstRow; @@ -1362,6 +1404,22 @@ static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, cons return TRUE; } +/*** + * Creates an iterator over the items which intersect lprc. + */ +static BOOL iterator_frameditems(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *lprc) +{ + RECT frame = *lprc; + POINT Origin; + + TRACE("(lprc=%s)\n", wine_dbgstr_rect(lprc)); + + LISTVIEW_GetOrigin(infoPtr, &Origin); + OffsetRect(&frame, -Origin.x, -Origin.y); + + return iterator_frameditems_absolute(i, infoPtr, &frame); +} + /*** * Creates an iterator over the items which intersect the visible region of hdc. */ @@ -1525,7 +1583,7 @@ static INT LISTVIEW_CreateHeader(LISTVIEW_INFO *infoPtr) SendMessageW(infoPtr->hwndHeader, HDM_SETUNICODEFORMAT, TRUE, 0); /* set header font */ - SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE); + SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, TRUE); LISTVIEW_UpdateSize(infoPtr); @@ -1536,6 +1594,13 @@ static inline void LISTVIEW_GetHeaderRect(const LISTVIEW_INFO *infoPtr, INT nSub { *lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader; } + +static inline BOOL LISTVIEW_IsHeaderEnabled(const LISTVIEW_INFO *infoPtr) +{ + return (infoPtr->uView == LV_VIEW_DETAILS || + infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) && + !(infoPtr->dwStyle & LVS_NOCOLUMNHEADER); +} static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem) { @@ -1683,14 +1748,15 @@ static inline INT LISTVIEW_GetCountPerColumn(const LISTVIEW_INFO *infoPtr) */ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData) { - INT nItem; - INT endidx,idx; - LVITEMW item; WCHAR buffer[MAX_PATH]; - DWORD lastKeyPressTimestamp = infoPtr->lastKeyPressTimestamp; + INT endidx, startidx; + DWORD prevTime; + LVITEMW item; + INT nItem; + INT diff; /* simple parameter checking */ - if (!charCode || !keyData) return 0; + if (!charCode || !keyData || infoPtr->nItemCount == 0) return 0; /* only allow the valid WM_CHARs through */ if (!isalnumW(charCode) && @@ -1705,86 +1771,95 @@ static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *infoPtr, WPARAM charCode, L charCode != '<' && charCode != ',' && charCode != '~') return 0; - /* if there's one item or less, there is no where to go */ - if (infoPtr->nItemCount <= 1) return 0; - /* update the search parameters */ + prevTime = infoPtr->lastKeyPressTimestamp; infoPtr->lastKeyPressTimestamp = GetTickCount(); - if (infoPtr->lastKeyPressTimestamp - lastKeyPressTimestamp < KEY_DELAY) { - if (infoPtr->nSearchParamLength < MAX_PATH-1) - infoPtr->szSearchParam[infoPtr->nSearchParamLength++]=charCode; + diff = infoPtr->lastKeyPressTimestamp - prevTime; + + if (diff >= 0 && diff < KEY_DELAY) + { + if (infoPtr->nSearchParamLength < MAX_PATH - 1) + infoPtr->szSearchParam[infoPtr->nSearchParamLength++] = charCode; + if (infoPtr->charCode != charCode) infoPtr->charCode = charCode = 0; - } else { - infoPtr->charCode=charCode; - infoPtr->szSearchParam[0]=charCode; - infoPtr->nSearchParamLength=1; - /* Redundant with the 1 char string */ - charCode=0; + } + else + { + infoPtr->charCode = charCode; + infoPtr->szSearchParam[0] = charCode; + infoPtr->nSearchParamLength = 1; + /* redundant with the 1 char string */ + charCode = 0; } /* and search from the current position */ - nItem=-1; - if (infoPtr->nFocusedItem >= 0) { - endidx=infoPtr->nFocusedItem; - idx=endidx; - /* if looking for single character match, - * then we must always move forward - */ - if (infoPtr->nSearchParamLength == 1) - idx++; - } else { - endidx=infoPtr->nItemCount; - idx=0; - } + nItem = -1; + endidx = infoPtr->nItemCount; - /* Let application handle this for virtual listview */ + /* should start from next after focused item, so next item that matches + will be selected, if there isn't any and focused matches it will be selected + on second search stage from beginning of the list */ + if (infoPtr->nFocusedItem >= 0 && infoPtr->nItemCount > 1) + startidx = infoPtr->nFocusedItem + 1; + else + startidx = 0; + + /* let application handle this for virtual listview */ if (infoPtr->dwStyle & LVS_OWNERDATA) { NMLVFINDITEMW nmlv; - LVFINDINFOW lvfi; - ZeroMemory(&lvfi, sizeof(lvfi)); - lvfi.flags = (LVFI_WRAP | LVFI_PARTIAL); - infoPtr->szSearchParam[infoPtr->nSearchParamLength] = '\0'; - lvfi.psz = infoPtr->szSearchParam; - nmlv.iStart = idx; - nmlv.lvfi = lvfi; + memset(&nmlv.lvfi, 0, sizeof(nmlv.lvfi)); + nmlv.lvfi.flags = (LVFI_WRAP | LVFI_PARTIAL); + nmlv.lvfi.psz = infoPtr->szSearchParam; + nmlv.iStart = startidx; + + infoPtr->szSearchParam[infoPtr->nSearchParamLength] = 0; nItem = notify_hdr(infoPtr, LVN_ODFINDITEMW, (LPNMHDR)&nmlv.hdr); - - if (nItem != -1) - LISTVIEW_KeySelection(infoPtr, nItem, FALSE); - - return 0; } + else + { + INT i = startidx; - do { - if (idx == infoPtr->nItemCount) { - if (endidx == infoPtr->nItemCount || endidx == 0) + /* first search in [startidx, endidx), on failure continue in [0, startidx) */ + while (1) + { + /* start from first item if not found with >= startidx */ + if (i == infoPtr->nItemCount && startidx > 0) + { + endidx = startidx; + startidx = 0; + } + + for (i = startidx; i < endidx; i++) + { + /* retrieve text */ + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = buffer; + item.cchTextMax = MAX_PATH; + if (!LISTVIEW_GetItemW(infoPtr, &item)) return 0; + + if (lstrncmpiW(item.pszText, infoPtr->szSearchParam, infoPtr->nSearchParamLength) == 0) + { + nItem = i; + break; + } + else if (nItem == -1 && lstrncmpiW(item.pszText, infoPtr->szSearchParam, 1) == 0) + { + /* this would work but we must keep looking for a longer match */ + nItem = i; + } + } + + /* found something or second search completed with any result */ + if (nItem != -1 || endidx != infoPtr->nItemCount) break; - idx=0; - } - - /* get item */ - item.mask = LVIF_TEXT; - item.iItem = idx; - item.iSubItem = 0; - item.pszText = buffer; - item.cchTextMax = MAX_PATH; - if (!LISTVIEW_GetItemW(infoPtr, &item)) return 0; - - /* check for a match */ - if (lstrncmpiW(item.pszText,infoPtr->szSearchParam,infoPtr->nSearchParamLength) == 0) { - nItem=idx; - break; - } else if ( (charCode != 0) && (nItem == -1) && (nItem != infoPtr->nFocusedItem) && - (lstrncmpiW(item.pszText,infoPtr->szSearchParam,1) == 0) ) { - /* This would work but we must keep looking for a longer match */ - nItem=idx; - } - idx++; - } while (idx != endidx); + }; + } if (nItem != -1) LISTVIEW_KeySelection(infoPtr, nItem, FALSE); @@ -1874,7 +1949,23 @@ static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *infoPtr) if (LISTVIEW_GetViewRect(infoPtr, &rcView)) horzInfo.nMax = rcView.right - rcView.left; } - + + if (LISTVIEW_IsHeaderEnabled(infoPtr)) + { + if (DPA_GetPtrCount(infoPtr->hdpaColumns)) + { + RECT rcHeader; + INT index; + + index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, + DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0); + + LISTVIEW_GetHeaderRect(infoPtr, index, &rcHeader); + horzInfo.nMax = rcHeader.right; + TRACE("horzInfo.nMax=%d\n", horzInfo.nMax); + } + } + horzInfo.fMask = SIF_RANGE | SIF_PAGE; horzInfo.nMax = max(horzInfo.nMax - 1, 0); dx = GetScrollPos(infoPtr->hwndSelf, SB_HORZ); @@ -1924,7 +2015,7 @@ static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *infoPtr) } /* Update the Header Control */ - if (infoPtr->uView == LV_VIEW_DETAILS) + if (infoPtr->hwndHeader) { horzInfo.fMask = SIF_POS; GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &horzInfo); @@ -2733,15 +2824,27 @@ static INT LISTVIEW_CalculateItemWidth(const LISTVIEW_INFO *infoPtr) } else /* LV_VIEW_SMALLICON, or LV_VIEW_LIST */ { + WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' }; + LVITEMW lvItem; INT i; - + + lvItem.mask = LVIF_TEXT; + lvItem.iSubItem = 0; + for (i = 0; i < infoPtr->nItemCount; i++) - nItemWidth = max(LISTVIEW_GetLabelWidth(infoPtr, i), nItemWidth); + { + lvItem.iItem = i; + lvItem.pszText = szDispText; + lvItem.cchTextMax = DISP_TEXT_SIZE; + if (LISTVIEW_GetItemW(infoPtr, &lvItem)) + nItemWidth = max(LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE), + nItemWidth); + } if (infoPtr->himlSmall) nItemWidth += infoPtr->iconSize.cx; if (infoPtr->himlState) nItemWidth += infoPtr->iconStateSize.cx; - nItemWidth = max(DEFAULT_COLUMN_WIDTH, nItemWidth + WIDTH_PADDING); + nItemWidth = max(DEFAULT_COLUMN_WIDTH, nItemWidth + WIDTH_PADDING); } return nItemWidth; @@ -2862,11 +2965,7 @@ static INT CALLBACK ranges_cmp(LPVOID range1, LPVOID range2, LPARAM flags) return cmp; } -#if DEBUG_RANGES -#define ranges_check(ranges, desc) ranges_assert(ranges, desc, __FUNCTION__, __LINE__) -#else -#define ranges_check(ranges, desc) do { } while(0) -#endif +#define ranges_check(ranges, desc) if (TRACE_ON(listview)) ranges_assert(ranges, desc, __FUNCTION__, __LINE__) static void ranges_assert(RANGES ranges, LPCSTR desc, const char *func, int line) { @@ -3091,28 +3190,30 @@ static BOOL ranges_del(RANGES ranges, RANGE range) TRACE("(%s)\n", debugrange(&range)); ranges_check(ranges, "before del"); - + /* we don't use DPAS_SORTED here, since we need * * to find the first overlapping range */ index = DPA_Search(ranges->hdpa, &range, 0, ranges_cmp, 0, 0); - while(index != -1) + while(index != -1) { chkrgn = DPA_GetPtr(ranges->hdpa, index); - - TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); + + TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); /* case 1: Same range */ if ( (chkrgn->upper == range.upper) && (chkrgn->lower == range.lower) ) { DPA_DeletePtr(ranges->hdpa, index); + Free(chkrgn); break; } /* case 2: engulf */ else if ( (chkrgn->upper <= range.upper) && - (chkrgn->lower >= range.lower) ) + (chkrgn->lower >= range.lower) ) { DPA_DeletePtr(ranges->hdpa, index); + Free(chkrgn); } /* case 3: overlap upper */ else if ( (chkrgn->upper <= range.upper) && @@ -3536,7 +3637,7 @@ static BOOL LISTVIEW_GetItemAtPt(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVIte return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE); } -static inline BOOL LISTVIEW_isHotTracking(const LISTVIEW_INFO *infoPtr) +static inline BOOL LISTVIEW_IsHotTracking(const LISTVIEW_INFO *infoPtr) { return ((infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) || (infoPtr->dwLvExStyle & LVS_EX_ONECLICKACTIVATE) || @@ -3561,9 +3662,13 @@ static inline BOOL LISTVIEW_isHotTracking(const LISTVIEW_INFO *infoPtr) * over the item for a certain period of time. * */ -static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, INT y) +static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, INT x, INT y) { - if (LISTVIEW_isHotTracking(infoPtr)) + NMHDR hdr; + + if (notify_hdr(infoPtr, NM_HOVER, &hdr)) return 0; + + if (LISTVIEW_IsHotTracking(infoPtr)) { LVITEMW item; POINT pt; @@ -3573,11 +3678,204 @@ static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, I if (LISTVIEW_GetItemAtPt(infoPtr, &item, pt)) LISTVIEW_SetSelection(infoPtr, item.iItem); + + SetFocus(infoPtr->hwndSelf); } return 0; } +#define SCROLL_LEFT 0x1 +#define SCROLL_RIGHT 0x2 +#define SCROLL_UP 0x4 +#define SCROLL_DOWN 0x8 + +/*** + * DESCRIPTION: + * Utility routine to draw and highlight items within a marquee selection rectangle. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] coords_orig : original co-ordinates of the cursor + * [I] coords_offs : offsetted coordinates of the cursor + * [I] offset : offset amount + * [I] scroll : Bitmask of which directions we should scroll, if at all + * + * RETURN: + * None. + */ +static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, LPPOINT coords_orig, LPPOINT coords_offs, LPPOINT offset, INT scroll) +{ + BOOL controlDown = FALSE; + LVITEMW item; + ITERATOR i; + RECT rect; + + if (coords_offs->x > infoPtr->marqueeOrigin.x) + { + rect.left = infoPtr->marqueeOrigin.x; + rect.right = coords_offs->x; + } + else + { + rect.left = coords_offs->x; + rect.right = infoPtr->marqueeOrigin.x; + } + + if (coords_offs->y > infoPtr->marqueeOrigin.y) + { + rect.top = infoPtr->marqueeOrigin.y; + rect.bottom = coords_offs->y; + } + else + { + rect.top = coords_offs->y; + rect.bottom = infoPtr->marqueeOrigin.y; + } + + /* Cancel out the old marquee rectangle and draw the new one */ + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); + + /* Scroll by the appropriate distance if applicable - speed up scrolling as + the cursor is further away */ + + if ((scroll & SCROLL_LEFT) && (coords_orig->x <= 0)) + LISTVIEW_Scroll(infoPtr, coords_orig->x, 0); + + if ((scroll & SCROLL_RIGHT) && (coords_orig->x >= infoPtr->rcList.right)) + LISTVIEW_Scroll(infoPtr, (coords_orig->x - infoPtr->rcList.right), 0); + + if ((scroll & SCROLL_UP) && (coords_orig->y <= 0)) + LISTVIEW_Scroll(infoPtr, 0, coords_orig->y); + + if ((scroll & SCROLL_DOWN) && (coords_orig->y >= infoPtr->rcList.bottom)) + LISTVIEW_Scroll(infoPtr, 0, (coords_orig->y - infoPtr->rcList.bottom)); + + /* Invert the items in the old marquee rectangle */ + iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect); + + while (iterator_next(&i)) + { + if (i.nItem > -1) + { + if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED) == LVIS_SELECTED) + item.state = 0; + else + item.state = LVIS_SELECTED; + + item.stateMask = LVIS_SELECTED; + + LISTVIEW_SetItemState(infoPtr, i.nItem, &item); + } + } + + iterator_destroy(&i); + + CopyRect(&infoPtr->marqueeRect, &rect); + + CopyRect(&infoPtr->marqueeDrawRect, &rect); + OffsetRect(&infoPtr->marqueeDrawRect, offset->x, offset->y); + + /* Iterate over the items within our marquee rectangle */ + iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect); + + if (GetKeyState(VK_CONTROL) & 0x8000) + controlDown = TRUE; + + while (iterator_next(&i)) + { + if (i.nItem > -1) + { + /* If CTRL is pressed, invert. If not, always select the item. */ + if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED))) + item.state = 0; + else + item.state = LVIS_SELECTED; + + item.stateMask = LVIS_SELECTED; + + LISTVIEW_SetItemState(infoPtr, i.nItem, &item); + } + } + + iterator_destroy(&i); + LISTVIEW_InvalidateRect(infoPtr, &rect); +} + +/*** + * DESCRIPTION: + * Called when we are in a marquee selection that involves scrolling the listview (ie, + * the cursor is outside the bounds of the client area). This is a TIMERPROC. + * + * PARAMETER(S): + * [I] hwnd : Handle to the listview + * [I] uMsg : WM_TIMER (ignored) + * [I] idEvent : The timer ID interpreted as a pointer to a LISTVIEW_INFO struct + * [I] dwTimer : The elapsed time (ignored) + * + * RETURN: + * None. + */ +static VOID CALLBACK LISTVIEW_ScrollTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + LISTVIEW_INFO *infoPtr; + SCROLLINFO scrollInfo; + POINT coords_orig; + POINT coords_offs; + POINT offset; + INT scroll = 0; + + infoPtr = (LISTVIEW_INFO *) idEvent; + + if (!infoPtr) + return; + + /* Get the current cursor position and convert to client coordinates */ + GetCursorPos(&coords_orig); + ScreenToClient(hWnd, &coords_orig); + + /* Ensure coordinates are within client bounds */ + coords_offs.x = max(min(coords_orig.x, infoPtr->rcList.right), 0); + coords_offs.y = max(min(coords_orig.y, infoPtr->rcList.bottom), 0); + + /* Get offset */ + LISTVIEW_GetOrigin(infoPtr, &offset); + + /* Offset coordinates by the appropriate amount */ + coords_offs.x -= offset.x; + coords_offs.y -= offset.y; + + scrollInfo.cbSize = sizeof(SCROLLINFO); + scrollInfo.fMask = SIF_ALL; + + /* Work out in which directions we can scroll */ + if (GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)) + { + if (scrollInfo.nPos != scrollInfo.nMin) + scroll |= SCROLL_UP; + + if (((scrollInfo.nPage + scrollInfo.nPos) - 1) != scrollInfo.nMax) + scroll |= SCROLL_DOWN; + } + + if (GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) + { + if (scrollInfo.nPos != scrollInfo.nMin) + scroll |= SCROLL_LEFT; + + if (((scrollInfo.nPage + scrollInfo.nPos) - 1) != scrollInfo.nMax) + scroll |= SCROLL_RIGHT; + } + + if (((coords_orig.x <= 0) && (scroll & SCROLL_LEFT)) || + ((coords_orig.y <= 0) && (scroll & SCROLL_UP)) || + ((coords_orig.x >= infoPtr->rcList.right) && (scroll & SCROLL_RIGHT)) || + ((coords_orig.y >= infoPtr->rcList.bottom) && (scroll & SCROLL_DOWN))) + { + LISTVIEW_MarqueeHighlight(infoPtr, &coords_orig, &coords_offs, &offset, scroll); + } +} + /*** * DESCRIPTION: * Called whenever WM_MOUSEMOVE is received. @@ -3592,8 +3890,6 @@ static LRESULT LISTVIEW_MouseHover(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, I */ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, INT y) { - TRACKMOUSEEVENT trackinfo; - if (!(fwKeys & MK_LBUTTON)) infoPtr->bLButtonDown = FALSE; @@ -3605,6 +3901,48 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN WORD wDragWidth = GetSystemMetrics(SM_CXDRAG); WORD wDragHeight= GetSystemMetrics(SM_CYDRAG); + if (infoPtr->bMarqueeSelect) + { + POINT coords_orig; + POINT coords_offs; + POINT offset; + + coords_orig.x = x; + coords_orig.y = y; + + /* Get offset */ + LISTVIEW_GetOrigin(infoPtr, &offset); + + /* Ensure coordinates are within client bounds */ + coords_offs.x = max(min(x, infoPtr->rcList.right), 0); + coords_offs.y = max(min(y, infoPtr->rcList.bottom), 0); + + /* Offset coordinates by the appropriate amount */ + coords_offs.x -= offset.x; + coords_offs.y -= offset.y; + + /* Enable the timer if we're going outside our bounds, in case the user doesn't + move the mouse again */ + + if ((x <= 0) || (y <= 0) || (x >= infoPtr->rcList.right) || + (y >= infoPtr->rcList.bottom)) + { + if (!infoPtr->bScrolling) + { + infoPtr->bScrolling = TRUE; + SetTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr, 1, LISTVIEW_ScrollTimer); + } + } + else + { + infoPtr->bScrolling = FALSE; + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); + } + + LISTVIEW_MarqueeHighlight(infoPtr, &coords_orig, &coords_offs, &offset, 0); + return 0; + } + rect.left = infoPtr->ptClickPos.x - wDragWidth; rect.right = infoPtr->ptClickPos.x + wDragWidth; rect.top = infoPtr->ptClickPos.y - wDragHeight; @@ -3640,17 +3978,42 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN if (!infoPtr->bDragging) { - NMLISTVIEW nmlv; - lvHitTestInfo.pt = infoPtr->ptClickPos; LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE); - ZeroMemory(&nmlv, sizeof(nmlv)); - nmlv.iItem = lvHitTestInfo.iItem; - nmlv.ptAction = infoPtr->ptClickPos; + /* If the click is outside the range of an item, begin a + highlight. If not, begin an item drag. */ + if (lvHitTestInfo.iItem == -1) + { + NMHDR hdr; - notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); - infoPtr->bDragging = TRUE; + /* If we're allowing multiple selections, send notification. + If return value is non-zero, cancel. */ + if (!(infoPtr->dwStyle & LVS_SINGLESEL) && (notify_hdr(infoPtr, LVN_MARQUEEBEGIN, &hdr) == 0)) + { + /* Store the absolute coordinates of the click */ + POINT offset; + LISTVIEW_GetOrigin(infoPtr, &offset); + + infoPtr->marqueeOrigin.x = infoPtr->ptClickPos.x - offset.x; + infoPtr->marqueeOrigin.y = infoPtr->ptClickPos.y - offset.y; + + /* Begin selection and capture mouse */ + infoPtr->bMarqueeSelect = TRUE; + SetCapture(infoPtr->hwndSelf); + } + } + else + { + NMLISTVIEW nmlv; + + ZeroMemory(&nmlv, sizeof(nmlv)); + nmlv.iItem = lvHitTestInfo.iItem; + nmlv.ptAction = infoPtr->ptClickPos; + + notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); + infoPtr->bDragging = TRUE; + } } return 0; @@ -3658,18 +4021,19 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN } /* see if we are supposed to be tracking mouse hovering */ - if (LISTVIEW_isHotTracking(infoPtr)) { - /* fill in the trackinfo struct */ + if (LISTVIEW_IsHotTracking(infoPtr)) { + TRACKMOUSEEVENT trackinfo; + trackinfo.cbSize = sizeof(TRACKMOUSEEVENT); trackinfo.dwFlags = TME_QUERY; - trackinfo.hwndTrack = infoPtr->hwndSelf; - trackinfo.dwHoverTime = infoPtr->dwHoverTime; /* see if we are already tracking this hwnd */ _TrackMouseEvent(&trackinfo); - if(!(trackinfo.dwFlags & TME_HOVER)) { - trackinfo.dwFlags = TME_HOVER; + if(!(trackinfo.dwFlags & TME_HOVER) || trackinfo.hwndTrack != infoPtr->hwndSelf) { + trackinfo.dwFlags = TME_HOVER; + trackinfo.dwHoverTime = infoPtr->dwHoverTime; + trackinfo.hwndTrack = infoPtr->hwndSelf; /* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */ _TrackMouseEvent(&trackinfo); @@ -3914,12 +4278,11 @@ static BOOL set_sub_item(const LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, *bChanged = TRUE; } - if (lpLVItem->mask & LVIF_IMAGE) - if (lpSubItem->hdr.iImage != lpLVItem->iImage) - { - lpSubItem->hdr.iImage = lpLVItem->iImage; - *bChanged = TRUE; - } + if ((lpLVItem->mask & LVIF_IMAGE) && (lpSubItem->hdr.iImage != lpLVItem->iImage)) + { + lpSubItem->hdr.iImage = lpLVItem->iImage; + *bChanged = TRUE; + } if ((lpLVItem->mask & LVIF_TEXT) && textcmpWT(lpSubItem->hdr.pszText, lpLVItem->pszText, isW)) { @@ -4089,7 +4452,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; if (nSubItem == 0) lvItem.mask |= LVIF_STATE; if (infoPtr->uView == LV_VIEW_DETAILS) lvItem.mask |= LVIF_INDENT; - lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK; + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK | LVIS_CUT; lvItem.iItem = nItem; lvItem.iSubItem = nSubItem; lvItem.state = 0; @@ -4192,14 +4555,23 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS } } - /* small icons */ + /* item icons */ himl = (infoPtr->uView == LV_VIEW_ICON ? infoPtr->himlNormal : infoPtr->himlSmall); if (himl && lvItem.iImage >= 0 && !IsRectEmpty(&rcIcon)) { + UINT style; + TRACE("iImage=%d\n", lvItem.iImage); + + if (lvItem.state & (LVIS_SELECTED | LVIS_CUT) && infoPtr->bFocus) + style = ILD_SELECTED; + else + style = ILD_NORMAL; + ImageList_DrawEx(himl, lvItem.iImage, hdc, rcIcon.left, rcIcon.top, - rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, infoPtr->clrBk, CLR_DEFAULT, - (lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus) ? ILD_SELECTED : ILD_NORMAL); + rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, infoPtr->clrBk, + lvItem.state & LVIS_CUT ? RGB(255, 255, 255) : CLR_DEFAULT, + style); } /* Don't bother painting item being edited */ @@ -4643,6 +5015,10 @@ enddraw: if ((infoPtr->uView == LV_VIEW_DETAILS) && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) LISTVIEW_RefreshReportGrid(infoPtr, hdc); + /* Draw marquee rectangle if appropriate */ + if (infoPtr->bMarqueeSelect) + DrawFocusRect(hdc, &infoPtr->marqueeDrawRect); + if (cdmode & CDRF_NOTIFYPOSTPAINT) notify_postpaint(infoPtr, &nmlvcd); @@ -4744,10 +5120,46 @@ static DWORD LISTVIEW_ApproximateViewRect(const LISTVIEW_INFO *infoPtr, INT nIte dwViewRect = MAKELONG(wWidth, wHeight); } + else if (infoPtr->uView == LV_VIEW_ICON) + { + UINT rows,cols; + UINT nItemWidth; + UINT nItemHeight; + + nItemWidth = infoPtr->iconSpacing.cx; + nItemHeight = infoPtr->iconSpacing.cy; + + if (nItemCount == -1) + nItemCount = infoPtr->nItemCount; + + if (wWidth == 0xffff) + wWidth = infoPtr->rcList.right - infoPtr->rcList.left; + + if (wWidth < nItemWidth) + wWidth = nItemWidth; + + cols = wWidth / nItemWidth; + if (cols > nItemCount) + cols = nItemCount; + if (cols < 1) + cols = 1; + + if (nItemCount) + { + rows = nItemCount / cols; + if (nItemCount % cols) + rows++; + } + else + rows = 0; + + wHeight = (nItemHeight * rows)+2; + wWidth = (nItemWidth * cols)+2; + + dwViewRect = MAKELONG(wWidth, wHeight); + } else if (infoPtr->uView == LV_VIEW_SMALLICON) FIXME("uView == LV_VIEW_SMALLICON: not implemented\n"); - else if (infoPtr->uView == LV_VIEW_ICON) - FIXME("uView == LV_VIEW_ICON: not implemented\n"); return dwViewRect; } @@ -4764,11 +5176,14 @@ static DWORD LISTVIEW_ApproximateViewRect(const LISTVIEW_INFO *infoPtr, INT nIte */ static LRESULT LISTVIEW_CancelEditLabel(LISTVIEW_INFO *infoPtr) { - /* handle value will be lost after LISTVIEW_EndEditLabelT */ - HWND edit = infoPtr->hwndEdit; + if (infoPtr->hwndEdit) + { + /* handle value will be lost after LISTVIEW_EndEditLabelT */ + HWND edit = infoPtr->hwndEdit; - LISTVIEW_EndEditLabelT(infoPtr, TRUE, IsWindowUnicode(infoPtr->hwndEdit)); - SendMessageW(edit, WM_CLOSE, 0, 0); + LISTVIEW_EndEditLabelT(infoPtr, TRUE, IsWindowUnicode(infoPtr->hwndEdit)); + SendMessageW(edit, WM_CLOSE, 0, 0); + } return TRUE; } @@ -4795,7 +5210,7 @@ static HIMAGELIST LISTVIEW_CreateDragImage(LISTVIEW_INFO *infoPtr, INT iItem, LP HIMAGELIST dragList = 0; TRACE("iItem=%d Count=%d\n", iItem, infoPtr->nItemCount); - if (iItem < 0 || iItem >= infoPtr->nItemCount) + if (iItem < 0 || iItem >= infoPtr->nItemCount || !lppt) return 0; rcItem.left = LVIR_BOUNDS; @@ -4855,6 +5270,8 @@ static BOOL LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr, BOOL destroy) HDPA hdpaSubItems = NULL; BOOL bSuppress; ITEMHDR *hdrItem; + ITEM_INFO *lpItem; + ITEM_ID *lpID; INT i, j; TRACE("()\n"); @@ -4876,13 +5293,20 @@ static BOOL LISTVIEW_DeleteAllItems(LISTVIEW_INFO *infoPtr, BOOL destroy) { if (!(infoPtr->dwStyle & LVS_OWNERDATA)) { - /* send LVN_DELETEITEM notification, if not suppressed - and if it is not a virtual listview */ - if (!bSuppress) notify_deleteitem(infoPtr, i); - hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, i); + /* send LVN_DELETEITEM notification, if not suppressed + and if it is not a virtual listview */ + if (!bSuppress) notify_deleteitem(infoPtr, i); + hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, i); + lpItem = DPA_GetPtr(hdpaSubItems, 0); + /* free id struct */ + j = DPA_GetPtrIndex(infoPtr->hdpaItemIds, lpItem->id); + lpID = DPA_GetPtr(infoPtr->hdpaItemIds, j); + DPA_DeletePtr(infoPtr->hdpaItemIds, j); + Free(lpID); + /* both item and subitem start with ITEMHDR header */ for (j = 0; j < DPA_GetPtrCount(hdpaSubItems); j++) { - hdrItem = DPA_GetPtr(hdpaSubItems, j); + hdrItem = DPA_GetPtr(hdpaSubItems, j); if (is_textW(hdrItem->pszText)) Free(hdrItem->pszText); Free(hdrItem); } @@ -5212,6 +5636,7 @@ static BOOL LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem) static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL isW) { HWND hwndSelf = infoPtr->hwndSelf; + WCHAR szDispText[DISP_TEXT_SIZE] = { 0 }; NMLVDISPINFOW dispInfo; INT editedItem = infoPtr->nEditLabelItem; BOOL bSame; @@ -5242,7 +5667,9 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL dispInfo.item.iItem = editedItem; dispInfo.item.iSubItem = 0; dispInfo.item.stateMask = ~0; - if (!LISTVIEW_GetItemW(infoPtr, &dispInfo.item)) + dispInfo.item.pszText = szDispText; + dispInfo.item.cchTextMax = DISP_TEXT_SIZE; + if (!LISTVIEW_GetItemT(infoPtr, &dispInfo.item, isW)) { res = FALSE; goto cleanup; @@ -5256,16 +5683,11 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL bSame = (lstrcmpW(dispInfo.item.pszText, tmp) == 0); textfreeT(tmp, FALSE); } - if (bSame) - { - res = TRUE; - goto cleanup; - } /* add the text from the edit in */ dispInfo.item.mask |= LVIF_TEXT; - dispInfo.item.pszText = pszText; - dispInfo.item.cchTextMax = textlenT(pszText, isW); + dispInfo.item.pszText = bSame ? NULL : pszText; + dispInfo.item.cchTextMax = bSame ? 0 : textlenT(pszText, isW); /* Do we need to update the Item Text */ if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW)) @@ -5279,6 +5701,11 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL goto cleanup; } if (!pszText) return TRUE; + if (bSame) + { + res = TRUE; + goto cleanup; + } if (!(infoPtr->dwStyle & LVS_OWNERDATA)) { @@ -5306,6 +5733,133 @@ cleanup: return res; } +/*** + * DESCRIPTION: + * Subclassed edit control windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * [I] isW : TRUE if input is Unicode + * + * RETURN: + * Zero. + */ +static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL isW) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0); + BOOL save = TRUE; + + TRACE("(hwnd=%p, uMsg=%x, wParam=%lx, lParam=%lx, isW=%d)\n", + hwnd, uMsg, wParam, lParam, isW); + + switch (uMsg) + { + case WM_GETDLGCODE: + return DLGC_WANTARROWS | DLGC_WANTALLKEYS; + + case WM_DESTROY: + { + WNDPROC editProc = infoPtr->EditWndProc; + infoPtr->EditWndProc = 0; + SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc); + return CallWindowProcT(editProc, hwnd, uMsg, wParam, lParam, isW); + } + + case WM_KEYDOWN: + if (VK_ESCAPE == (INT)wParam) + { + save = FALSE; + break; + } + else if (VK_RETURN == (INT)wParam) + break; + + default: + return CallWindowProcT(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam, isW); + } + + /* kill the edit */ + if (infoPtr->hwndEdit) + LISTVIEW_EndEditLabelT(infoPtr, save, isW); + + SendMessageW(hwnd, WM_CLOSE, 0, 0); + return 0; +} + +/*** + * DESCRIPTION: + * Subclassed edit control Unicode windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * + * RETURN: + */ +static LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return EditLblWndProcT(hwnd, uMsg, wParam, lParam, TRUE); +} + +/*** + * DESCRIPTION: + * Subclassed edit control ANSI windproc function + * + * PARAMETER(S): + * [I] hwnd : the edit window handle + * [I] uMsg : the message that is to be processed + * [I] wParam : first message parameter + * [I] lParam : second message parameter + * + * RETURN: + */ +static LRESULT CALLBACK EditLblWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return EditLblWndProcT(hwnd, uMsg, wParam, lParam, FALSE); +} + +/*** + * DESCRIPTION: + * Creates a subclassed edit control + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] text : initial text for the edit + * [I] style : the window style + * [I] isW : TRUE if input is Unicode + * + * RETURN: + */ +static HWND CreateEditLabelT(LISTVIEW_INFO *infoPtr, LPCWSTR text, BOOL isW) +{ + static const DWORD style = WS_CHILDWINDOW|WS_CLIPSIBLINGS|ES_LEFT|ES_AUTOHSCROLL|WS_BORDER|WS_VISIBLE; + HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_HINSTANCE); + HWND hedit; + + TRACE("(%p, text=%s, isW=%d)\n", infoPtr, debugtext_t(text, isW), isW); + + /* Window will be resized and positioned after LVN_BEGINLABELEDIT */ + if (isW) + hedit = CreateWindowW(WC_EDITW, text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); + else + hedit = CreateWindowA(WC_EDITA, (LPCSTR)text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); + + if (!hedit) return 0; + + infoPtr->EditWndProc = (WNDPROC) + (isW ? SetWindowLongPtrW(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcW) : + SetWindowLongPtrA(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcA) ); + + SendMessageW(hedit, WM_SETFONT, (WPARAM)infoPtr->hFont, FALSE); + + return hedit; +} + /*** * DESCRIPTION: * Begin in place editing of specified list view item @@ -5361,7 +5915,7 @@ static HWND LISTVIEW_EditLabelT(LISTVIEW_INFO *infoPtr, INT nItem, BOOL isW) dispInfo.item.cchTextMax = DISP_TEXT_SIZE; if (!LISTVIEW_GetItemT(infoPtr, &dispInfo.item, isW)) return 0; - infoPtr->hwndEdit = CreateEditLabelT(infoPtr, dispInfo.item.pszText, WS_VISIBLE, isW); + infoPtr->hwndEdit = CreateEditLabelT(infoPtr, dispInfo.item.pszText, isW); if (!infoPtr->hwndEdit) return 0; if (notify_dispinfoT(infoPtr, LVN_BEGINLABELEDITW, &dispInfo, isW)) @@ -5525,7 +6079,8 @@ static INT LISTVIEW_FindItemW(const LISTVIEW_INFO *infoPtr, INT nStart, if (!lpFindInfo || nItem < 0) return -1; lvItem.mask = 0; - if (lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL)) + if (lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL) || + lpFindInfo->flags & LVFI_SUBSTRING) { lvItem.mask |= LVIF_TEXT; lvItem.pszText = szDispText; @@ -5586,12 +6141,13 @@ again: else continue; } - + if (lvItem.mask & LVIF_TEXT) { - if (lpFindInfo->flags & LVFI_PARTIAL) + if (lpFindInfo->flags & (LVFI_PARTIAL | LVFI_SUBSTRING)) { - if (strstrW(lvItem.pszText, lpFindInfo->psz) == NULL) continue; + WCHAR *p = strstrW(lvItem.pszText, lpFindInfo->psz); + if (!p || p != lvItem.pszText) continue; } else { @@ -5600,7 +6156,7 @@ again: } if (!bNearest) return nItem; - + /* This is very inefficient. To do a good job here, * we need a sorted array of (x,y) item positions */ LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position); @@ -5645,7 +6201,8 @@ again: static INT LISTVIEW_FindItemA(const LISTVIEW_INFO *infoPtr, INT nStart, const LVFINDINFOA *lpFindInfo) { - BOOL hasText = lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL); + BOOL hasText = lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL) || + lpFindInfo->flags & LVFI_SUBSTRING; LVFINDINFOW fiw; INT res; LPWSTR strW = NULL; @@ -5842,8 +6399,13 @@ static HIMAGELIST LISTVIEW_GetImageList(const LISTVIEW_INFO *infoPtr, INT nImage switch (nImageList) { case LVSIL_NORMAL: return infoPtr->himlNormal; - case LVSIL_SMALL: return infoPtr->himlSmall; - case LVSIL_STATE: return infoPtr->himlState; + case LVSIL_SMALL: return infoPtr->himlSmall; + case LVSIL_STATE: return infoPtr->himlState; + case LVSIL_GROUPHEADER: + FIXME("LVSIL_GROUPHEADER not supported\n"); + break; + default: + WARN("got unknown imagelist index - %d\n", nImageList); } return NULL; } @@ -6000,7 +6562,7 @@ static BOOL LISTVIEW_GetItemT(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, if (isubitem) { - SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, isubitem); + SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, isubitem); pItemHdr = lpSubItem ? &lpSubItem->hdr : &callbackHdr; if (!lpSubItem) { @@ -6384,7 +6946,7 @@ static BOOL LISTVIEW_GetItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPRECT */ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc) { - POINT Position; + POINT Position, Origin; LVITEMW lvItem; INT nColumn; @@ -6392,7 +6954,7 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR nColumn = lprc->top; - TRACE("(nItem=%d, nSubItem=%d)\n", nItem, lprc->top); + TRACE("(nItem=%d, nSubItem=%d, type=%d)\n", nItem, lprc->top, lprc->left); /* On WinNT, a subitem of '0' calls LISTVIEW_GetItemRect */ if (lprc->top == 0) return LISTVIEW_GetItemRect(infoPtr, nItem, lprc); @@ -6418,6 +6980,7 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR } if (!LISTVIEW_GetItemPosition(infoPtr, nItem, &Position)) return FALSE; + LISTVIEW_GetOrigin(infoPtr, &Origin); if (nColumn < 0 || nColumn >= DPA_GetPtrCount(infoPtr->hdpaColumns)) return FALSE; @@ -6425,7 +6988,6 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR lvItem.iItem = nItem; lvItem.iSubItem = nColumn; - if (lvItem.mask && !LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE; switch(lprc->left) { case LVIR_ICON: @@ -6442,39 +7004,12 @@ static BOOL LISTVIEW_GetSubItemRect(const LISTVIEW_INFO *infoPtr, INT nItem, LPR return FALSE; } - OffsetRect(lprc, 0, Position.y); + OffsetRect(lprc, Origin.x, Position.y); + TRACE("return rect %s\n", wine_dbgstr_rect(lprc)); + return TRUE; } - -/*** - * DESCRIPTION: - * Retrieves the width of a label. - * - * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure - * - * RETURN: - * SUCCESS : string width (in pixels) - * FAILURE : zero - */ -static INT LISTVIEW_GetLabelWidth(const LISTVIEW_INFO *infoPtr, INT nItem) -{ - WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' }; - LVITEMW lvItem; - - TRACE("(nItem=%d)\n", nItem); - - lvItem.mask = LVIF_TEXT; - lvItem.iItem = nItem; - lvItem.iSubItem = 0; - lvItem.pszText = szDispText; - lvItem.cchTextMax = DISP_TEXT_SIZE; - if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return 0; - - return LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE); -} - /*** * DESCRIPTION: * Retrieves the spacing between listview control items. @@ -6918,6 +7453,14 @@ static INT LISTVIEW_HitTest(const LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, } } TRACE("lpht->iSubItem=%d\n", lpht->iSubItem); + + /* if we're outside horizontal columns bounds there's nothing to test further */ + if (lpht->iSubItem == -1) + { + lpht->iItem = -1; + lpht->flags = LVHT_NOWHERE; + return -1; + } } TRACE("lpht->flags=0x%x\n", lpht->flags); @@ -7067,9 +7610,9 @@ static INT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, while (i < infoPtr->nItemCount) { hItem = DPA_GetPtr( infoPtr->hdpaItems, i); - item_s = (ITEM_INFO*)DPA_GetPtr(hItem, 0); + item_s = DPA_GetPtr(hItem, 0); - cmpv = textcmpWT(item_s->hdr.pszText, lpLVItem->pszText, TRUE); + cmpv = textcmpWT(item_s->hdr.pszText, lpLVItem->pszText, isW); if (infoPtr->dwStyle & LVS_SORTDESCENDING) cmpv *= -1; if (cmpv >= 0) break; @@ -7451,7 +7994,7 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, /* insert item in header control */ nNewColumn = SendMessageW(infoPtr->hwndHeader, isW ? HDM_INSERTITEMW : HDM_INSERTITEMA, - (WPARAM)nColumn, (LPARAM)&hdi); + nColumn, (LPARAM)&hdi); if (nNewColumn == -1) return -1; if (nNewColumn != nColumn) ERR("nColumn=%d, nNewColumn=%d\n", nColumn, nNewColumn); @@ -7470,7 +8013,14 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, SUBITEM_INFO *lpSubItem; HDPA hdpaSubItems; INT nItem, i; - + LVITEMW item; + BOOL changed; + + item.iSubItem = nNewColumn; + item.mask = LVIF_TEXT | LVIF_IMAGE; + item.iImage = I_IMAGECALLBACK; + item.pszText = LPSTR_TEXTCALLBACKW; + for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) { hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, nItem); @@ -7480,6 +8030,10 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, if (lpSubItem->iSubItem >= nNewColumn) lpSubItem->iSubItem++; } + + /* add new subitem for each item */ + item.iItem = nItem; + set_sub_item(infoPtr, &item, isW, &changed); } } @@ -7534,7 +8088,7 @@ static BOOL LISTVIEW_SetColumnT(const LISTVIEW_INFO *infoPtr, INT nColumn, column_fill_hditem(infoPtr, &hdi, nColumn, lpColumn, isW); /* set header item attributes */ - bResult = SendMessageW(infoPtr->hwndHeader, isW ? HDM_SETITEMW : HDM_SETITEMA, (WPARAM)nColumn, (LPARAM)&hdi); + bResult = SendMessageW(infoPtr->hwndHeader, isW ? HDM_SETITEMW : HDM_SETITEMA, nColumn, (LPARAM)&hdi); if (!bResult) return FALSE; if (lpColumn->mask & LVCF_FMT) @@ -7774,10 +8328,18 @@ static DWORD LISTVIEW_SetExtendedListViewStyle(LISTVIEW_INFO *infoPtr, DWORD dwM LISTVIEW_SetItemState(infoPtr, -1, &item); himl = LISTVIEW_CreateCheckBoxIL(infoPtr); + if(!(infoPtr->dwStyle & LVS_SHAREIMAGELISTS)) + ImageList_Destroy(infoPtr->himlState); } - LISTVIEW_SetImageList(infoPtr, LVSIL_STATE, himl); + himl = LISTVIEW_SetImageList(infoPtr, LVSIL_STATE, himl); + /* checkbox list replaces prevous custom list or... */ + if(((infoPtr->dwLvExStyle & LVS_EX_CHECKBOXES) && + !(infoPtr->dwStyle & LVS_SHAREIMAGELISTS)) || + /* ...previous was checkbox list */ + (dwOldExStyle & LVS_EX_CHECKBOXES)) + ImageList_Destroy(himl); } - + if((infoPtr->dwLvExStyle ^ dwOldExStyle) & LVS_EX_HEADERDRAGDROP) { DWORD dwStyle; @@ -7805,6 +8367,16 @@ static DWORD LISTVIEW_SetExtendedListViewStyle(LISTVIEW_INFO *infoPtr, DWORD dwM LISTVIEW_SetBkColor(infoPtr, CLR_NONE); } + if((infoPtr->dwLvExStyle ^ dwOldExStyle) & LVS_EX_HEADERINALLVIEWS) + { + if (infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) + LISTVIEW_CreateHeader(infoPtr); + else + ShowWindow(infoPtr->hwndHeader, SW_HIDE); + LISTVIEW_UpdateSize(infoPtr); + LISTVIEW_UpdateScroll(infoPtr); + } + LISTVIEW_InvalidateList(infoPtr); return dwOldExStyle; } @@ -8105,34 +8677,35 @@ static BOOL LISTVIEW_SetItemCount(LISTVIEW_INFO *infoPtr, INT nItems, DWORD dwFl * SUCCESS : TRUE * FAILURE : FALSE */ -static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT pt) +static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT *pt) { - POINT Origin; + POINT Origin, Pt; - TRACE("(nItem=%d, &pt=%s\n", nItem, wine_dbgstr_point(&pt)); + TRACE("(nItem=%d, pt=%s\n", nItem, wine_dbgstr_point(pt)); - if (nItem < 0 || nItem >= infoPtr->nItemCount || + if (!pt || nItem < 0 || nItem >= infoPtr->nItemCount || !(infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON)) return FALSE; + Pt = *pt; LISTVIEW_GetOrigin(infoPtr, &Origin); /* This point value seems to be an undocumented feature. * The best guess is that it means either at the origin, * or at true beginning of the list. I will assume the origin. */ - if ((pt.x == -1) && (pt.y == -1)) - pt = Origin; + if ((Pt.x == -1) && (Pt.y == -1)) + Pt = Origin; if (infoPtr->uView == LV_VIEW_ICON) { - pt.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; - pt.y -= ICON_TOP_PADDING; + Pt.x -= (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; + Pt.y -= ICON_TOP_PADDING; } - pt.x -= Origin.x; - pt.y -= Origin.y; + Pt.x -= Origin.x; + Pt.y -= Origin.y; infoPtr->bAutoarrange = FALSE; - return LISTVIEW_MoveIconTo(infoPtr, nItem, &pt, FALSE); + return LISTVIEW_MoveIconTo(infoPtr, nItem, &Pt, FALSE); } /*** @@ -8671,7 +9244,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING); infoPtr->nEditLabelItem = -1; infoPtr->nLButtonDownItem = -1; - infoPtr->dwHoverTime = -1; /* default system hover time */ + infoPtr->dwHoverTime = HOVER_DEFAULT; /* default system hover time */ infoPtr->nMeasureItemHeight = 0; infoPtr->xTrackLine = -1; /* no track line */ infoPtr->itemEdit.fEnabled = FALSE; @@ -8728,7 +9301,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) map_style_view(infoPtr); infoPtr->notifyFormat = SendMessageW(infoPtr->hwndNotify, WM_NOTIFYFORMAT, - (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY); + (WPARAM)infoPtr->hwndSelf, NF_QUERY); /* on error defaulting to ANSI notifications */ if (infoPtr->notifyFormat == 0) infoPtr->notifyFormat = NFR_ANSI; @@ -8772,10 +9345,14 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) * Success: 0 * Failure: -1 */ -static LRESULT LISTVIEW_Destroy(const LISTVIEW_INFO *infoPtr) +static LRESULT LISTVIEW_Destroy(LISTVIEW_INFO *infoPtr) { HTHEME theme = GetWindowTheme(infoPtr->hwndSelf); CloseThemeData(theme); + + /* delete all items */ + LISTVIEW_DeleteAllItems(infoPtr, TRUE); + return 0; } @@ -8791,7 +9368,7 @@ static LRESULT LISTVIEW_Destroy(const LISTVIEW_INFO *infoPtr) * SUCCESS : TRUE * FAILURE : FALSE */ -static BOOL LISTVIEW_Enable(const LISTVIEW_INFO *infoPtr, BOOL bEnable) +static BOOL LISTVIEW_Enable(const LISTVIEW_INFO *infoPtr) { if (infoPtr->dwStyle & LVS_OWNERDRAWFIXED) InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); @@ -9045,37 +9622,32 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode, scrollInfo.fMask = SIF_POS; scrollInfo.nPos = nNewScrollPos; nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE); - + /* carry on only if it really changed */ if (nNewScrollPos == nOldScrollPos) return 0; - - if (infoPtr->uView == LV_VIEW_DETAILS) - LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos); - + + if (infoPtr->hwndHeader) LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos); + /* now adjust to client coordinates */ nScrollDiff = nOldScrollPos - nNewScrollPos; if (infoPtr->uView == LV_VIEW_LIST) nScrollDiff *= infoPtr->nItemWidth; - + /* and scroll the window */ scroll_list(infoPtr, nScrollDiff, 0); - return 0; + return 0; } static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta) { INT gcWheelDelta = 0; INT pulScrollLines = 3; - SCROLLINFO scrollInfo; TRACE("(wheelDelta=%d)\n", wheelDelta); SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); gcWheelDelta -= wheelDelta; - scrollInfo.cbSize = sizeof(SCROLLINFO); - scrollInfo.fMask = SIF_POS; - switch(infoPtr->uView) { case LV_VIEW_ICON: @@ -9233,7 +9805,21 @@ static LRESULT LISTVIEW_KillFocus(LISTVIEW_INFO *infoPtr) /* if we have a focus rectangle, get rid of it */ LISTVIEW_ShowFocusRect(infoPtr, FALSE); - + + /* if have a marquee selection, stop it */ + if (infoPtr->bMarqueeSelect) + { + /* Remove the marquee rectangle and release our mouse capture */ + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeRect); + ReleaseCapture(); + + SetRect(&infoPtr->marqueeRect, 0, 0, 0, 0); + + infoPtr->bMarqueeSelect = FALSE; + infoPtr->bScrolling = FALSE; + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); + } + /* set window focus flag */ infoPtr->bFocus = FALSE; @@ -9312,6 +9898,8 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN infoPtr->bLButtonDown = TRUE; infoPtr->ptClickPos = pt; infoPtr->bDragging = FALSE; + infoPtr->bMarqueeSelect = FALSE; + infoPtr->bScrolling = FALSE; lvHitTestInfo.pt.x = x; lvHitTestInfo.pt.y = y; @@ -9389,6 +9977,9 @@ static LRESULT LISTVIEW_LButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, IN } else { + if (!infoPtr->bFocus) + SetFocus(infoPtr->hwndSelf); + /* remove all selections */ if (!(wKey & MK_CONTROL) && !(wKey & MK_SHIFT)) LISTVIEW_DeselectAll(infoPtr); @@ -9433,9 +10024,23 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT LISTVIEW_SetSelection(infoPtr, infoPtr->nLButtonDownItem); infoPtr->nLButtonDownItem = -1; - if (infoPtr->bDragging) + if (infoPtr->bDragging || infoPtr->bMarqueeSelect) { + /* Remove the marquee rectangle and release our mouse capture */ + if (infoPtr->bMarqueeSelect) + { + LISTVIEW_InvalidateRect(infoPtr, &infoPtr->marqueeDrawRect); + ReleaseCapture(); + } + + SetRect(&infoPtr->marqueeRect, 0, 0, 0, 0); + SetRect(&infoPtr->marqueeDrawRect, 0, 0, 0, 0); + infoPtr->bDragging = FALSE; + infoPtr->bMarqueeSelect = FALSE; + infoPtr->bScrolling = FALSE; + + KillTimer(infoPtr->hwndSelf, (UINT_PTR) infoPtr); return 0; } @@ -9471,28 +10076,27 @@ static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT */ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr) { - TRACE("()\n"); + INT i; - /* delete all items */ - LISTVIEW_DeleteAllItems(infoPtr, TRUE); + TRACE("()\n"); /* destroy data structure */ DPA_Destroy(infoPtr->hdpaItems); DPA_Destroy(infoPtr->hdpaItemIds); DPA_Destroy(infoPtr->hdpaPosX); DPA_Destroy(infoPtr->hdpaPosY); + /* columns */ + for (i = 0; i < DPA_GetPtrCount(infoPtr->hdpaColumns); i++) + Free(DPA_GetPtr(infoPtr->hdpaColumns, i)); DPA_Destroy(infoPtr->hdpaColumns); ranges_destroy(infoPtr->selectionRanges); /* destroy image lists */ if (!(infoPtr->dwStyle & LVS_SHAREIMAGELISTS)) { - if (infoPtr->himlNormal) - ImageList_Destroy(infoPtr->himlNormal); - if (infoPtr->himlSmall) - ImageList_Destroy(infoPtr->himlSmall); - if (infoPtr->himlState) - ImageList_Destroy(infoPtr->himlState); + ImageList_Destroy(infoPtr->himlNormal); + ImageList_Destroy(infoPtr->himlSmall); + ImageList_Destroy(infoPtr->himlState); } /* destroy font, bkgnd brush */ @@ -9675,6 +10279,9 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE case HDN_DIVIDERDBLCLICKW: case HDN_DIVIDERDBLCLICKA: + /* FIXME: for LVS_EX_HEADERINALLVIEWS and not LV_VIEW_DETAILS + we should use LVSCW_AUTOSIZE_USEHEADER, helper rework or + split needed for that */ LISTVIEW_SetColumnWidth(infoPtr, lpnmh->iItem, LVSCW_AUTOSIZE); notify_forward_header(infoPtr, lpnmh); break; @@ -9704,7 +10311,8 @@ static BOOL LISTVIEW_NCPaint(const LISTVIEW_INFO *infoPtr, HRGN region) int cxEdge = GetSystemMetrics (SM_CXEDGE), cyEdge = GetSystemMetrics (SM_CYEDGE); - if (!theme) return FALSE; + if (!theme) + return DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)region, 0); GetWindowRect(infoPtr->hwndSelf, &r); @@ -9725,7 +10333,7 @@ static BOOL LISTVIEW_NCPaint(const LISTVIEW_INFO *infoPtr, HRGN region) /* Call default proc to get the scrollbars etc. painted */ DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)cliprgn, 0); - return TRUE; + return FALSE; } /*** @@ -9975,20 +10583,24 @@ static LRESULT LISTVIEW_RButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, INT x, INT * TRUE if cursor is set * FALSE otherwise */ -static BOOL LISTVIEW_SetCursor(const LISTVIEW_INFO *infoPtr, HWND hwnd, UINT nHittest, UINT wMouseMsg) +static BOOL LISTVIEW_SetCursor(const LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { LVHITTESTINFO lvHitTestInfo; - if(!(LISTVIEW_isHotTracking(infoPtr))) return FALSE; + if (!LISTVIEW_IsHotTracking(infoPtr)) goto forward; - if(!infoPtr->hHotCursor) return FALSE; + if (!infoPtr->hHotCursor) goto forward; GetCursorPos(&lvHitTestInfo.pt); - if (LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, FALSE, FALSE) < 0) return FALSE; + if (LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, FALSE, FALSE) < 0) goto forward; SetCursor(infoPtr->hHotCursor); return TRUE; + +forward: + + return DefWindowProcW(infoPtr->hwndSelf, WM_SETCURSOR, wParam, lParam); } /*** @@ -10161,7 +10773,9 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr) infoPtr->rcList.bottom -= GetSystemMetrics(SM_CYHSCROLL); infoPtr->rcList.bottom = max (infoPtr->rcList.bottom - 2, 0); } - else if (infoPtr->uView == LV_VIEW_DETAILS) + + /* if control created invisible header isn't created */ + if (infoPtr->hwndHeader) { HDLAYOUT hl; WINDOWPOS wp; @@ -10169,15 +10783,24 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr) hl.prc = &infoPtr->rcList; hl.pwpos = ℘ SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl ); - TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy); - SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, - wp.flags | ((infoPtr->dwStyle & LVS_NOCOLUMNHEADER) - ? SWP_HIDEWINDOW : SWP_SHOWWINDOW)); - TRACE(" after SWP wp=%d,%d (%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy); + TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy); + + if (LISTVIEW_IsHeaderEnabled(infoPtr)) + wp.flags |= SWP_SHOWWINDOW; + else + { + wp.flags |= SWP_HIDEWINDOW; + wp.cy = 0; + } + + SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags); + TRACE(" after SWP wp=%d,%d (%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy); infoPtr->rcList.top = max(wp.cy, 0); - infoPtr->rcList.top += (infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) ? 2 : 0; } + /* extra padding for grid */ + if (infoPtr->uView == LV_VIEW_DETAILS && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) + infoPtr->rcList.top += 2; TRACE(" rcList=%s\n", wine_dbgstr_rect(&infoPtr->rcList)); } @@ -10258,7 +10881,7 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, LISTVIEW_UpdateItemSize(infoPtr); } - if (uNewView == LVS_REPORT) + if (uNewView == LVS_REPORT || infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) { if ((lpss->styleOld ^ lpss->styleNew) & LVS_NOCOLUMNHEADER) { @@ -10300,14 +10923,13 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, * Processes WM_STYLECHANGING messages. * * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure * [I] wStyleType : window style type (normal or extended) * [I0] lpss : window style information * * RETURN: * Zero */ -static INT LISTVIEW_StyleChanging(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, +static INT LISTVIEW_StyleChanging(WPARAM wStyleType, STYLESTRUCT *lpss) { TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n", @@ -10337,7 +10959,7 @@ static INT LISTVIEW_StyleChanging(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, * RETURN: * Zero */ -static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, BOOL bShown, INT iStatus) +static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, WPARAM bShown, LPARAM iStatus) { /* header delayed creation */ if ((infoPtr->uView == LV_VIEW_DETAILS) && bShown) @@ -10348,7 +10970,7 @@ static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, BOOL bShown, INT iSta ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL); } - return 0; + return DefWindowProcW(infoPtr->hwndSelf, WM_SHOWWINDOW, bShown, iStatus); } /*** @@ -10402,7 +11024,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(hwnd, 0); - TRACE("(uMsg=%x wParam=%lx lParam=%lx)\n", uMsg, wParam, lParam); + TRACE("(hwnd=%p uMsg=%x wParam=%lx lParam=%lx)\n", hwnd, uMsg, wParam, lParam); if (!infoPtr && (uMsg != WM_NCCREATE)) return DefWindowProcW(hwnd, uMsg, wParam, lParam); @@ -10430,12 +11052,10 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case LVM_DELETEITEM: return LISTVIEW_DeleteItem(infoPtr, (INT)wParam); - case LVM_EDITLABELW: - return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, TRUE); - case LVM_EDITLABELA: - return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, FALSE); - + case LVM_EDITLABELW: + return (LRESULT)LISTVIEW_EditLabelT(infoPtr, (INT)wParam, + uMsg == LVM_EDITLABELW); /* case LVM_ENABLEGROUPVIEW: */ case LVM_ENSUREVISIBLE: @@ -10456,10 +11076,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return infoPtr->uCallbackMask; case LVM_GETCOLUMNA: - return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE); - case LVM_GETCOLUMNW: - return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE); + return LISTVIEW_GetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, + uMsg == LVM_GETCOLUMNW); case LVM_GETCOLUMNORDERARRAY: return LISTVIEW_GetColumnOrderArray(infoPtr, (INT)wParam, (LPINT)lParam); @@ -10507,10 +11126,8 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return FALSE; case LVM_GETITEMA: - return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, FALSE); - case LVM_GETITEMW: - return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_GetItemExtT(infoPtr, (LPLVITEMW)lParam, uMsg == LVM_GETITEMW); case LVM_GETITEMCOUNT: return infoPtr->nItemCount; @@ -10528,10 +11145,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_GetItemState(infoPtr, (INT)wParam, (UINT)lParam); case LVM_GETITEMTEXTA: - return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, FALSE); - case LVM_GETITEMTEXTW: - return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_GetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, + uMsg == LVM_GETITEMTEXTW); case LVM_GETNEXTITEM: return LISTVIEW_GetNextItem(infoPtr, (INT)wParam, LOWORD(lParam)); @@ -10558,10 +11174,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return infoPtr->nSelectionMark; case LVM_GETSTRINGWIDTHA: - return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, FALSE); - case LVM_GETSTRINGWIDTHW: - return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, TRUE); + return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, + uMsg == LVM_GETSTRINGWIDTHW); case LVM_GETSUBITEMRECT: return LISTVIEW_GetSubItemRect(infoPtr, (UINT)wParam, (LPRECT)lParam); @@ -10603,20 +11218,17 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_HitTest(infoPtr, (LPLVHITTESTINFO)lParam, FALSE, TRUE); case LVM_INSERTCOLUMNA: - return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE); - case LVM_INSERTCOLUMNW: - return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE); + return LISTVIEW_InsertColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, + uMsg == LVM_INSERTCOLUMNW); /* case LVM_INSERTGROUP: */ /* case LVM_INSERTGROUPSORTED: */ case LVM_INSERTITEMA: - return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, FALSE); - case LVM_INSERTITEMW: - return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_InsertItemT(infoPtr, (LPLVITEMW)lParam, uMsg == LVM_INSERTITEMW); /* case LVM_INSERTMARKHITTEST: */ @@ -10655,10 +11267,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TRUE; case LVM_SETCOLUMNA: - return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, FALSE); - case LVM_SETCOLUMNW: - return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, TRUE); + return LISTVIEW_SetColumnT(infoPtr, (INT)wParam, (LPLVCOLUMNW)lParam, + uMsg == LVM_SETCOLUMNW); case LVM_SETCOLUMNORDERARRAY: return LISTVIEW_SetColumnOrderArray(infoPtr, (INT)wParam, (LPINT)lParam); @@ -10680,7 +11291,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_SetHotItem(infoPtr, (INT)wParam); case LVM_SETHOVERTIME: - return LISTVIEW_SetHoverTime(infoPtr, (DWORD)wParam); + return LISTVIEW_SetHoverTime(infoPtr, (DWORD)lParam); case LVM_SETICONSPACING: return LISTVIEW_SetIconSpacing(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam)); @@ -10709,22 +11320,20 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) POINT pt; pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); - return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, pt); + return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, &pt); } case LVM_SETITEMPOSITION32: - if (lParam == 0) return FALSE; - return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, *((POINT*)lParam)); + return LISTVIEW_SetItemPosition(infoPtr, (INT)wParam, (POINT*)lParam); case LVM_SETITEMSTATE: if (lParam == 0) return FALSE; return LISTVIEW_SetItemState(infoPtr, (INT)wParam, (LPLVITEMW)lParam); case LVM_SETITEMTEXTA: - return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, FALSE); - case LVM_SETITEMTEXTW: - return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, TRUE); + return LISTVIEW_SetItemTextT(infoPtr, (INT)wParam, (LPLVITEMW)lParam, + uMsg == LVM_SETITEMTEXTW); /* case LVM_SETOUTLINECOLOR: */ @@ -10759,11 +11368,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /* case LVM_SORTGROUPS: */ case LVM_SORTITEMS: - return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, (LPARAM)wParam, FALSE); - case LVM_SORTITEMSEX: - return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, (LPARAM)wParam, TRUE); - + return LISTVIEW_SortItems(infoPtr, (PFNLVCOMPARE)lParam, wParam, + uMsg == LVM_SORTITEMSEX); case LVM_SUBITEMHITTEST: return LISTVIEW_HitTest(infoPtr, (LPLVHITTESTINFO)lParam, TRUE, FALSE); @@ -10792,7 +11399,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_Destroy(infoPtr); case WM_ENABLE: - return LISTVIEW_Enable(infoPtr, (BOOL)wParam); + return LISTVIEW_Enable(infoPtr); case WM_ERASEBKGND: return LISTVIEW_EraseBkgnd(infoPtr, (HDC)wParam); @@ -10825,15 +11432,13 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_MouseMove (infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_MOUSEHOVER: - return LISTVIEW_MouseHover(infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); + return LISTVIEW_MouseHover(infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_NCDESTROY: return LISTVIEW_NCDestroy(infoPtr); case WM_NCPAINT: - if (LISTVIEW_NCPaint(infoPtr, (HRGN)wParam)) - return 0; - goto fwd_msg; + return LISTVIEW_NCPaint(infoPtr, (HRGN)wParam); case WM_NOTIFY: if (lParam && ((LPNMHDR)lParam)->hwndFrom == infoPtr->hwndHeader) @@ -10859,9 +11464,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_RButtonUp(infoPtr, (WORD)wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_SETCURSOR: - if(LISTVIEW_SetCursor(infoPtr, (HWND)wParam, LOWORD(lParam), HIWORD(lParam))) - return TRUE; - goto fwd_msg; + return LISTVIEW_SetCursor(infoPtr, wParam, lParam); case WM_SETFOCUS: return LISTVIEW_SetFocus(infoPtr, (HWND)wParam); @@ -10873,8 +11476,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_SetRedraw(infoPtr, (BOOL)wParam); case WM_SHOWWINDOW: - LISTVIEW_ShowWindow(infoPtr, (BOOL)wParam, (INT)lParam); - return DefWindowProcW(hwnd, uMsg, wParam, lParam); + return LISTVIEW_ShowWindow(infoPtr, wParam, lParam); case WM_SIZE: return LISTVIEW_Size(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam)); @@ -10883,7 +11485,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return LISTVIEW_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam); case WM_STYLECHANGING: - return LISTVIEW_StyleChanging(infoPtr, wParam, (LPSTYLESTRUCT)lParam); + return LISTVIEW_StyleChanging(wParam, (LPSTYLESTRUCT)lParam); case WM_SYSCOLORCHANGE: COMCTL32_RefreshSysColors(); @@ -10923,8 +11525,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg)) ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam); - fwd_msg: - /* call default window procedure */ return DefWindowProcW(hwnd, uMsg, wParam, lParam); } @@ -10984,6 +11584,11 @@ void LISTVIEW_Unregister(void) */ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { + + TRACE("(%p %x %x %lx)\n", infoPtr, HIWORD(wParam), LOWORD(wParam), lParam); + + if (!infoPtr->hwndEdit) return 0; + switch (HIWORD(wParam)) { case EN_UPDATE: @@ -11003,7 +11608,7 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP /* Select font to get the right dimension of the string */ hFont = (HFONT)SendMessageW(infoPtr->hwndEdit, WM_GETFONT, 0, 0); - if(hFont != 0) + if (hFont) { hOldFont = SelectObject(hdc, hFont); } @@ -11016,16 +11621,10 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP GetTextMetricsW(hdc, &textMetric); sz.cx += (textMetric.tmMaxCharWidth * 2); - SetWindowPos ( - infoPtr->hwndEdit, - HWND_TOP, - 0, - 0, - sz.cx, - rect.bottom - rect.top, - SWP_DRAWFRAME|SWP_NOMOVE); + SetWindowPos(infoPtr->hwndEdit, NULL, 0, 0, sz.cx, + rect.bottom - rect.top, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOZORDER); } - if(hFont != 0) + if (hFont) SelectObject(hdc, hOldFont); ReleaseDC(infoPtr->hwndEdit, hdc); @@ -11035,6 +11634,7 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP case EN_KILLFOCUS: { LISTVIEW_CancelEditLabel(infoPtr); + break; } default: @@ -11043,133 +11643,3 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP return 0; } - - -/*** - * DESCRIPTION: - * Subclassed edit control windproc function - * - * PARAMETER(S): - * [I] hwnd : the edit window handle - * [I] uMsg : the message that is to be processed - * [I] wParam : first message parameter - * [I] lParam : second message parameter - * [I] isW : TRUE if input is Unicode - * - * RETURN: - * Zero. - */ -static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL isW) -{ - LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0); - BOOL save = TRUE; - - TRACE("(hwnd=%p, uMsg=%x, wParam=%lx, lParam=%lx, isW=%d)\n", - hwnd, uMsg, wParam, lParam, isW); - - switch (uMsg) - { - case WM_GETDLGCODE: - return DLGC_WANTARROWS | DLGC_WANTALLKEYS; - - case WM_DESTROY: - { - WNDPROC editProc = infoPtr->EditWndProc; - infoPtr->EditWndProc = 0; - SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc); - return CallWindowProcT(editProc, hwnd, uMsg, wParam, lParam, isW); - } - - case WM_KEYDOWN: - if (VK_ESCAPE == (INT)wParam) - { - save = FALSE; - break; - } - else if (VK_RETURN == (INT)wParam) - break; - - default: - return CallWindowProcT(infoPtr->EditWndProc, hwnd, uMsg, wParam, lParam, isW); - } - - /* kill the edit */ - if (infoPtr->hwndEdit) - LISTVIEW_EndEditLabelT(infoPtr, save, isW); - - SendMessageW(hwnd, WM_CLOSE, 0, 0); - return 0; -} - -/*** - * DESCRIPTION: - * Subclassed edit control Unicode windproc function - * - * PARAMETER(S): - * [I] hwnd : the edit window handle - * [I] uMsg : the message that is to be processed - * [I] wParam : first message parameter - * [I] lParam : second message parameter - * - * RETURN: - */ -static LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return EditLblWndProcT(hwnd, uMsg, wParam, lParam, TRUE); -} - -/*** - * DESCRIPTION: - * Subclassed edit control ANSI windproc function - * - * PARAMETER(S): - * [I] hwnd : the edit window handle - * [I] uMsg : the message that is to be processed - * [I] wParam : first message parameter - * [I] lParam : second message parameter - * - * RETURN: - */ -static LRESULT CALLBACK EditLblWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return EditLblWndProcT(hwnd, uMsg, wParam, lParam, FALSE); -} - -/*** - * DESCRIPTION: - * Creates a subclassed edit control - * - * PARAMETER(S): - * [I] infoPtr : valid pointer to the listview structure - * [I] text : initial text for the edit - * [I] style : the window style - * [I] isW : TRUE if input is Unicode - * - * RETURN: - */ -static HWND CreateEditLabelT(LISTVIEW_INFO *infoPtr, LPCWSTR text, DWORD style, BOOL isW) -{ - WCHAR editName[5] = { 'E', 'd', 'i', 't', '\0' }; - HWND hedit; - HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_HINSTANCE); - - TRACE("(text=%s, ..., isW=%d)\n", debugtext_t(text, isW), isW); - - style |= WS_CHILDWINDOW|WS_CLIPSIBLINGS|ES_LEFT|ES_AUTOHSCROLL|WS_BORDER; - - /* Window will be resized and positioned after LVN_BEGINLABELEDIT */ - if (isW) - hedit = CreateWindowW(editName, text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); - else - hedit = CreateWindowA("Edit", (LPCSTR)text, style, 0, 0, 0, 0, infoPtr->hwndSelf, 0, hinst, 0); - - if (!hedit) return 0; - - infoPtr->EditWndProc = (WNDPROC) - (isW ? SetWindowLongPtrW(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcW) : - SetWindowLongPtrA(hedit, GWLP_WNDPROC, (DWORD_PTR)EditLblWndProcA) ); - - SendMessageW(hedit, WM_SETFONT, (WPARAM)infoPtr->hFont, FALSE); - - return hedit; -} diff --git a/dll/win32/comdlg32/comdlg32.rbuild b/dll/win32/comdlg32/comdlg32.rbuild index d9ea84d9e28..70c0322000f 100644 --- a/dll/win32/comdlg32/comdlg32.rbuild +++ b/dll/win32/comdlg32/comdlg32.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/dll/win32/crypt32/cert.c b/dll/win32/crypt32/cert.c index c25e612574f..12c013e7a4a 100644 --- a/dll/win32/crypt32/cert.c +++ b/dll/win32/crypt32/cert.c @@ -113,9 +113,21 @@ BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext) { - FIXME("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, - ppCertContext); - return FALSE; + static int calls; + PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore; + + if (!(calls++)) + FIXME("(%p, %p, %08x, %p): semi-stub\n", hCertStore, pCertContext, + dwAddDisposition, ppCertContext); + if (store->dwMagic != WINE_CRYPTCERTSTORE_MAGIC) + return FALSE; + if (store->type == StoreTypeCollection) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + return CertAddCertificateContextToStore(hCertStore, pCertContext, + dwAddDisposition, ppCertContext); } PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, diff --git a/dll/win32/crypt32/chain.c b/dll/win32/crypt32/chain.c index 1724f4254fe..e951ef8e9c5 100644 --- a/dll/win32/crypt32/chain.c +++ b/dll/win32/crypt32/chain.c @@ -152,6 +152,20 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, return engine; } +typedef struct _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT +{ + DWORD cbSize; + HCERTSTORE hRestrictedRoot; + HCERTSTORE hRestrictedTrust; + HCERTSTORE hRestrictedOther; + DWORD cAdditionalStore; + HCERTSTORE *rghAdditionalStore; + DWORD dwFlags; + DWORD dwUrlRetrievalTimeout; + DWORD MaximumCachedCertificates; + DWORD CycleDetectionModulus; +} CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT; + BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, HCERTCHAINENGINE *phChainEngine) { @@ -159,7 +173,8 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, TRACE("(%p, %p)\n", pConfig, phChainEngine); - if (pConfig->cbSize != sizeof(*pConfig)) + if (pConfig->cbSize != sizeof(CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT) + && pConfig->cbSize != sizeof(CERT_CHAIN_ENGINE_CONFIG)) { SetLastError(E_INVALIDARG); return FALSE; @@ -171,7 +186,10 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, HCERTSTORE root; HCERTCHAINENGINE engine; - if (pConfig->hRestrictedRoot) + if (pConfig->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && + pConfig->hExclusiveRoot) + root = CertDuplicateStore(pConfig->hExclusiveRoot); + else if (pConfig->hRestrictedRoot) root = CertDuplicateStore(pConfig->hRestrictedRoot); else root = CertOpenSystemStoreW(0, rootW); @@ -3017,7 +3035,31 @@ static BOOL match_dns_to_subject_alt_name(PCERT_EXTENSION ext, { TRACE_(chain)("dNSName: %s\n", debugstr_w( subjectName->rgAltEntry[i].u.pwszDNSName)); - if (!strcmpiW(server_name, + if (subjectName->rgAltEntry[i].u.pwszDNSName[0] == '*') + { + LPCWSTR server_name_dot; + + /* Matching a wildcard: a wildcard matches a single name + * component, which is terminated by a dot. RFC 1034 + * doesn't define whether multiple wildcards are allowed, + * but I will assume that they are not until proven + * otherwise. RFC 1034 also states that 'the "*" label + * always matches at least one whole label and sometimes + * more, but always whole labels.' Native crypt32 does not + * match more than one label with a wildcard, so I do the + * same here. Thus, a wildcard only accepts the first + * label, then requires an exact match of the remaining + * string. + */ + server_name_dot = strchrW(server_name, '.'); + if (server_name_dot) + { + if (!strcmpiW(server_name_dot, + subjectName->rgAltEntry[i].u.pwszDNSName + 1)) + matches = TRUE; + } + } + else if (!strcmpiW(server_name, subjectName->rgAltEntry[i].u.pwszDNSName)) matches = TRUE; } diff --git a/dll/win32/crypt32/regstore.c b/dll/win32/crypt32/regstore.c index 296b0c9a5b9..f4b4295835a 100644 --- a/dll/win32/crypt32/regstore.c +++ b/dll/win32/crypt32/regstore.c @@ -479,6 +479,10 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, ret = CRYPT_RegFlushStore(store, dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG); break; + case CERT_STORE_CTRL_AUTO_RESYNC: + FIXME("CERT_STORE_CTRL_AUTO_RESYNC: stub\n"); + ret = TRUE; + break; default: FIXME("%d: stub\n", dwCtrlType); ret = FALSE; diff --git a/dll/win32/crypt32/store.c b/dll/win32/crypt32/store.c index a8923949974..da3de5650db 100644 --- a/dll/win32/crypt32/store.c +++ b/dll/win32/crypt32/store.c @@ -855,7 +855,16 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); - if (dwAddDisposition != CERT_STORE_ADD_ALWAYS) + switch (dwAddDisposition) + { + case CERT_STORE_ADD_ALWAYS: + break; + case CERT_STORE_ADD_NEW: + case CERT_STORE_ADD_REPLACE_EXISTING: + case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: + case CERT_STORE_ADD_USE_EXISTING: + case CERT_STORE_ADD_NEWER: + case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: { BYTE hashToAdd[20]; DWORD size = sizeof(hashToAdd); @@ -870,6 +879,12 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, NULL); } + break; + } + default: + FIXME("Unimplemented add disposition %d\n", dwAddDisposition); + SetLastError(E_INVALIDARG); + ret = FALSE; } switch (dwAddDisposition) @@ -940,10 +955,6 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, else toAdd = CertDuplicateCertificateContext(pCertContext); break; - default: - FIXME("Unimplemented add disposition %d\n", dwAddDisposition); - SetLastError(E_INVALIDARG); - ret = FALSE; } if (toAdd) diff --git a/dll/win32/devmgr/advprop.c b/dll/win32/devmgr/advprop.c index b7c38678769..b7af67e9dc1 100644 --- a/dll/win32/devmgr/advprop.c +++ b/dll/win32/devmgr/advprop.c @@ -165,26 +165,6 @@ UpdateDriverDetailsDlg(IN HWND hwndDlg, &DriverInfoData)) { HSPFILEQ queueHandle; - DWORD HiVal, LoVal; - WCHAR szTime[25]; - - HiVal = (DriverInfoData.DriverVersion >> 32); - if (HiVal) - { - swprintf (szTime, L"%d.%d", HIWORD(HiVal), LOWORD(HiVal)); - LoVal = (DriverInfoData.DriverVersion & 0xFFFFFFFF); - if (HIWORD(LoVal)) - { - swprintf(&szTime[wcslen(szTime)], L".%d", HIWORD(LoVal)); - if (LOWORD(LoVal)) - { - swprintf(&szTime[wcslen(szTime)], L".%d", LOWORD(LoVal)); - } - } - SetDlgItemTextW(hwndDlg, IDC_FILEVERSION, szTime); - } - SetDlgItemText(hwndDlg, IDC_FILEPROVIDER, DriverInfoData.ProviderName); - queueHandle = SetupOpenFileQueue(); if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE) @@ -225,6 +205,15 @@ UpdateDriverDetailsDlg(IN HWND hwndDlg, (void)ListView_SetColumn(hDriversListView, 0, &lvc); + + /* highlight the first item from list */ + if (ListView_GetSelectedCount(hDriversListView) != 0) + { + ListView_SetItemState(hDriversListView, + 0, + LVIS_FOCUSED | LVIS_SELECTED, + LVIS_FOCUSED | LVIS_SELECTED); + } } } @@ -234,6 +223,124 @@ UpdateDriverDetailsDlg(IN HWND hwndDlg, } +static VOID +UpdateDriverVersionInfoDetails(IN HWND hwndDlg, + IN LPCWSTR lpszDriverPath) +{ + DWORD dwHandle; + DWORD dwVerInfoSize; + LPVOID lpData = NULL; + LPVOID lpInfo; + UINT uInfoLen; + DWORD dwLangId; + WCHAR szLangInfo[255]; + WCHAR szLangPath[MAX_PATH]; + LPWSTR lpCompanyName = NULL; + LPWSTR lpFileVersion = NULL; + LPWSTR lpLegalCopyright = NULL; + LPWSTR lpDigitalSigner = NULL; + UINT uBufLen; + WCHAR szNotAvailable[255]; + + /* extract version info from selected file */ + dwVerInfoSize = GetFileVersionInfoSize(lpszDriverPath, + &dwHandle); + if (!dwVerInfoSize) + goto done; + + lpData = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwVerInfoSize); + if (!lpData) + goto done; + + if (!GetFileVersionInfo(lpszDriverPath, + dwHandle, + dwVerInfoSize, + lpData)) + goto done; + + if (!VerQueryValue(lpData, + L"\\VarFileInfo\\Translation", + &lpInfo, + &uInfoLen)) + goto done; + + dwLangId = *(LPDWORD)lpInfo; + swprintf(szLangInfo, L"\\StringFileInfo\\%04x%04x\\", + LOWORD(dwLangId), HIWORD(dwLangId)); + + /* read CompanyName */ + wcscpy(szLangPath, szLangInfo); + wcscat(szLangPath, L"CompanyName"); + + VerQueryValue(lpData, + szLangPath, + (void **)&lpCompanyName, + (PUINT)&uBufLen); + + /* read FileVersion */ + wcscpy(szLangPath, szLangInfo); + wcscat(szLangPath, L"FileVersion"); + + VerQueryValue(lpData, + szLangPath, + (void **)&lpFileVersion, + (PUINT)&uBufLen); + + /* read LegalTrademarks */ + wcscpy(szLangPath, szLangInfo); + wcscat(szLangPath, L"LegalCopyright"); + + VerQueryValue(lpData, + szLangPath, + (void **)&lpLegalCopyright, + (PUINT)&uBufLen); + + /* TODO: read digital signer info */ + +done: + if (!LoadString(hDllInstance, + IDS_NOTAVAILABLE, + szNotAvailable, + sizeof(szNotAvailable) / sizeof(WCHAR))) + { + wcscpy(szNotAvailable, L"n/a"); + } + + /* update labels */ + if (!lpCompanyName) + lpCompanyName = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_FILEPROVIDER, + lpCompanyName); + + if (!lpFileVersion) + lpFileVersion = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_FILEVERSION, + lpFileVersion); + + if (!lpLegalCopyright) + lpLegalCopyright = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_FILECOPYRIGHT, + lpLegalCopyright); + + if (!lpDigitalSigner) + lpDigitalSigner = szNotAvailable; + SetDlgItemText(hwndDlg, + IDC_DIGITALSIGNER, + lpDigitalSigner); + + /* release version info */ + if (lpData) + HeapFree(GetProcessHeap(), + 0, + lpData); +} + + static INT_PTR CALLBACK DriverDetailsDlgProc(IN HWND hwndDlg, @@ -256,6 +363,7 @@ DriverDetailsDlgProc(IN HWND hwndDlg, switch (LOWORD(wParam)) { case IDOK: + case IDCANCEL: { EndDialog(hwndDlg, IDOK); @@ -303,6 +411,53 @@ DriverDetailsDlgProc(IN HWND hwndDlg, Ret = TRUE; break; } + + case WM_NOTIFY: + { + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; + HWND hDriversListView = GetDlgItem(hwndDlg, + IDC_DRIVERFILES); + + if (ListView_GetSelectedCount(hDriversListView) == 0) + { + /* nothing is selected - empty the labels */ + SetDlgItemText(hwndDlg, + IDC_FILEPROVIDER, + NULL); + SetDlgItemText(hwndDlg, + IDC_FILEVERSION, + NULL); + SetDlgItemText(hwndDlg, + IDC_FILECOPYRIGHT, + NULL); + SetDlgItemText(hwndDlg, + IDC_DIGITALSIGNER, + NULL); + } + else if (pnmv->uNewState != 0) + { + /* extract version info and update the labels */ + WCHAR szDriverPath[MAX_PATH]; + + ListView_GetItemText(hDriversListView, + pnmv->iItem, + pnmv->iSubItem, + szDriverPath, + MAX_PATH); + + UpdateDriverVersionInfoDetails(hwndDlg, + szDriverPath); + } + } + } + break; + } } } diff --git a/dll/win32/devmgr/devmgr.rbuild b/dll/win32/devmgr/devmgr.rbuild index b746bd39b9c..fafa15fb898 100644 --- a/dll/win32/devmgr/devmgr.rbuild +++ b/dll/win32/devmgr/devmgr.rbuild @@ -5,6 +5,7 @@ setupapi advapi32 user32 + version devmgr.rc advprop.c devprblm.c diff --git a/dll/win32/devmgr/lang/bg-BG.rc b/dll/win32/devmgr/lang/bg-BG.rc index 7ade5f18be8..ec278d57810 100644 --- a/dll/win32/devmgr/lang/bg-BG.rc +++ b/dll/win32/devmgr/lang/bg-BG.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Ďîęŕçâŕíĺ íŕ ďîäđîáíîńňč çŕ ôŕéëîâĺňĺ íŕ âîäŕ÷ŕ.", -1, 105, 110, 141, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Ďîäđîáíîńňčňĺ çŕ ôŕéëîâĺňĺ íŕ âîäŕ÷ŕ" FONT 8, "MS Shell Dlg" @@ -186,15 +186,15 @@ BEGIN CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 - LTEXT "Äîńňŕâ÷čę:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 82, 134, 140, 8 - LTEXT "Ôŕéëîâŕ âĺđńč˙:", -1, 14, 150, 70, 16 - LTEXT "", IDC_FILEVERSION, 82, 150, 140, 8 - LTEXT "Âúçďđîčçâîäńňâĺíč ďđŕâŕ:", -1, 14, 166, 70, 16 - LTEXT "", IDC_FILECOPYRIGHT, 82, 166, 140, 8 - LTEXT "Ďîäďčńŕë öčôđîâî:", -1, 14, 182, 70, 16 - LTEXT "", IDC_DIGITALSIGNER, 82, 182, 140, 8 - PUSHBUTTON "Äîáđĺ", IDOK, 167, 228, 50, 14 + LTEXT "Äîńňŕâ÷čę:", -1, 14, 134, 66, 8 + EDITTEXT IDC_FILEPROVIDER, 82, 134, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Ôŕéëîâŕ âĺđńč˙:", -1, 14, 150, 66, 16 + EDITTEXT IDC_FILEVERSION, 82, 150, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Âúçďđîčçâîäńňâĺíč ďđŕâŕ:", -1, 14, 166, 66, 16 + EDITTEXT IDC_FILECOPYRIGHT, 82, 166, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Ďîäďčńŕë öčôđîâî:", -1, 14, 182, 66, 16 + EDITTEXT IDC_DIGITALSIGNER, 82, 182, 140, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "Äîáđĺ", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/cs-CZ.rc b/dll/win32/devmgr/lang/cs-CZ.rc index aa7a56e21c5..3716d97803d 100644 --- a/dll/win32/devmgr/lang/cs-CZ.rc +++ b/dll/win32/devmgr/lang/cs-CZ.rc @@ -16,7 +16,7 @@ BEGIN IDS_LOCATIONSTR "Umístění %1!u! (%2)" IDS_DEVCODE " (Kód %1!u!)" IDS_DEVCODE2 " (Kód %2!u!)" - IDS_ENABLEDEVICE "Použít toto zařízení (zapnout)" + IDS_ENABLEDEVICE "Používat toto zařízení (zapnout)" IDS_DISABLEDEVICE "Nepoužívat toto zařízení (vypnout)" IDS_UNKNOWNDEVICE "Neznámé zařízení" IDS_NODRIVERLOADED "Pro toto zařízení nejsou nainstalovány žádné ovladače." @@ -166,7 +166,7 @@ FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX - LTEXT "Poskytovatel ovladače:", -1, 37, 39, 60, 8, SS_NOPREFIX + LTEXT "Zprostředkovatel:", -1, 37, 39, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVPROVIDER, 100, 39, 146, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Datum ovladače:", -1, 37, 53, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVDATE, 100, 53, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY @@ -178,7 +178,7 @@ BEGIN LTEXT "Zobrazí detaily souborů ovladače.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detaily souborů ovladače" FONT 8, "MS Shell Dlg" @@ -189,15 +189,15 @@ BEGIN CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 - LTEXT "Poskytovatel:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 - LTEXT "Verze souboru:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 - LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 - LTEXT "Digitální podpis:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + LTEXT "Zprostředkovatel:", -1, 14, 134, 66, 8 + EDITTEXT IDC_FILEPROVIDER, 80, 134, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Verze souboru:", -1, 14, 150, 66, 8 + EDITTEXT IDC_FILEVERSION, 80, 150, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Autorská práva:", -1, 14, 166, 66, 8 + EDITTEXT IDC_FILECOPYRIGHT, 80, 166, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digitální podpis:", -1, 14, 182, 66, 8 + EDITTEXT IDC_DIGITALSIGNER, 80, 182, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/de-DE.rc b/dll/win32/devmgr/lang/de-DE.rc index 91769ff11f5..a027c814c63 100644 --- a/dll/win32/devmgr/lang/de-DE.rc +++ b/dll/win32/devmgr/lang/de-DE.rc @@ -176,7 +176,7 @@ BEGIN LTEXT "Einzelheiten über die Treiberdateien anzeigen.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Treiberdateidetails" FONT 8, "MS Shell Dlg" @@ -188,14 +188,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Anbieter:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Dateiversion:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Signaturgeber:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/el-GR.rc b/dll/win32/devmgr/lang/el-GR.rc index 9ccb338000f..e51db8729ed 100644 --- a/dll/win32/devmgr/lang/el-GR.rc +++ b/dll/win32/devmgr/lang/el-GR.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "ËĺđôďěÝńĺéĺň Áń÷ĺßůí Ďäçăďý" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "ĐńďěçčĺőôŢň:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "¸ęäďóç áń÷ĺßďő:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Äéęáéţěáôá:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Digital Signer:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/en-US.rc b/dll/win32/devmgr/lang/en-US.rc index 64b44f2e0af..27009dddb78 100644 --- a/dll/win32/devmgr/lang/en-US.rc +++ b/dll/win32/devmgr/lang/en-US.rc @@ -176,7 +176,7 @@ BEGIN LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Driver File Details" FONT 8, "MS Shell Dlg" @@ -188,14 +188,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Provider:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "File version:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Digital Signer:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/es-ES.rc b/dll/win32/devmgr/lang/es-ES.rc index 2b728c199e8..d3e80b4950a 100644 --- a/dll/win32/devmgr/lang/es-ES.rc +++ b/dll/win32/devmgr/lang/es-ES.rc @@ -94,30 +94,30 @@ END STRINGTABLE BEGIN - IDS_PROP_DEVICEID "Device Instance ID" - IDS_PROP_HARDWAREIDS "Hardware IDs" - IDS_PROP_COMPATIBLEIDS "Compatible IDs" - IDS_PROP_MATCHINGDEVICEID "Matching Device ID" - IDS_PROP_SERVICE "Service" - IDS_PROP_ENUMERATOR "Enumerator" - IDS_PROP_CAPABILITIES "Capabilities" - IDS_PROP_DEVNODEFLAGS "Devnode Flags" - IDS_PROP_CONFIGFLAGS "Config Flags" - IDS_PROP_CSCONFIGFLAGS "CSConfig Flags" - IDS_PROP_EJECTIONRELATIONS "Ejection Relations" - IDS_PROP_REMOVALRELATIONS "Removal Relations" - IDS_PROP_BUSRELATIONS "Bus Relations" - IDS_PROP_DEVUPPERFILTERS "Device Upper Filters" - IDS_PROP_DEVLOWERFILTERS "Device Lower Filters" - IDS_PROP_CLASSUPPERFILTERS "Class Upper Filters" - IDS_PROP_CLASSLOWERFILTERS "Class Lower Filters" - IDS_PROP_CLASSINSTALLER "Class Installers" - IDS_PROP_CLASSCOINSTALLER "Class Coinstallers" - IDS_PROP_DEVICECOINSTALLER "Device Coinstallers" - IDS_PROP_FIRMWAREREVISION "Firmware Revision" - IDS_PROP_CURRENTPOWERSTATE "Current Power State" - IDS_PROP_POWERCAPABILITIES "Power Capabilities" - IDS_PROP_POWERSTATEMAPPINGS "Power State Mappings" + IDS_PROP_DEVICEID "Id. de instancia de dispositivo" + IDS_PROP_HARDWAREIDS "Identificadores de hardware" + IDS_PROP_COMPATIBLEIDS "Identificadores compatibles" + IDS_PROP_MATCHINGDEVICEID "Id. de dispositivo coincidente" + IDS_PROP_SERVICE "Servicio" + IDS_PROP_ENUMERATOR "Enumerador" + IDS_PROP_CAPABILITIES "Recursos" + IDS_PROP_DEVNODEFLAGS "Marcadores Devnode" + IDS_PROP_CONFIGFLAGS "Marcadores Config" + IDS_PROP_CSCONFIGFLAGS "Marcadores CSConfig" + IDS_PROP_EJECTIONRELATIONS "Relaciones de extracción" + IDS_PROP_REMOVALRELATIONS "Relaciones de eliminación" + IDS_PROP_BUSRELATIONS "Relaciones de bus" + IDS_PROP_DEVUPPERFILTERS "Filtros superiores de dispositivo" + IDS_PROP_DEVLOWERFILTERS "Filtros inferiores de dispositivo" + IDS_PROP_CLASSUPPERFILTERS "Filtros superiores de clase" + IDS_PROP_CLASSLOWERFILTERS "Filtros inferiores de clase" + IDS_PROP_CLASSINSTALLER "Instaladores de clase" + IDS_PROP_CLASSCOINSTALLER "Coinstaladores de clase" + IDS_PROP_DEVICECOINSTALLER "Coinstaladores de dispositivo" + IDS_PROP_FIRMWAREREVISION "Revisión de firmware" + IDS_PROP_CURRENTPOWERSTATE "Estado actual de energía" + IDS_PROP_POWERCAPABILITIES "Capacidad de energía" + IDS_PROP_POWERSTATEMAPPINGS "Asignaciones de estado de energía" END IDD_HARDWARE DIALOGEX DISCARDABLE 0, 0, 300, 400 @@ -176,7 +176,7 @@ BEGIN LTEXT "Ver detalles de los archivos del controlador.", -1, 100, 110, 150, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detalles de archivo de controlador" FONT 8, "MS Shell Dlg" @@ -188,19 +188,19 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Proveedor:", -1, 10, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versión:", -1, 10, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 10, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Firmante Digital:", -1, 10, 182, 60, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "Aceptar", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "Aceptar", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Details" +CAPTION "Detalles" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 @@ -213,7 +213,7 @@ END IDD_DEVICERESOURCES DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Resources" +CAPTION "Recursos" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 @@ -222,7 +222,7 @@ END IDD_DEVICEPOWER DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Power" +CAPTION "Administración de energía" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 diff --git a/dll/win32/devmgr/lang/fr-FR.rc b/dll/win32/devmgr/lang/fr-FR.rc index 1d1e580b314..697998f32bc 100644 --- a/dll/win32/devmgr/lang/fr-FR.rc +++ b/dll/win32/devmgr/lang/fr-FR.rc @@ -174,7 +174,7 @@ BEGIN LTEXT "Voir les détails ŕ propos des fichiers du Pilote.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Fichiers du Pilote" FONT 8, "MS Shell Dlg" @@ -186,14 +186,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Fournisseur :", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Version :", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright :", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Signature numérique :", -1, 14, 182, 80, 8 - LTEXT "", IDC_DIGITALSIGNER, 96, 182, 125, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 96, 182, 125, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/hu-HU.rc b/dll/win32/devmgr/lang/hu-HU.rc index 23180c63b5c..daf66ad14ee 100644 --- a/dll/win32/devmgr/lang/hu-HU.rc +++ b/dll/win32/devmgr/lang/hu-HU.rc @@ -174,6 +174,28 @@ BEGIN LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME +CAPTION "Driver File Details" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "", IDC_DEVICON, 7, 7, 20, 20 + LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX + LTEXT "&Driver files:", -1, 7, 36, 204, 8 + CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | + LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 + LTEXT "Provider:", -1, 14, 134, 50, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "File version:", -1, 14, 150, 50, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Copyright:", -1, 14, 166, 50, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digital Signer:", -1, 14, 182, 50, 8 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 +END + IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Details" diff --git a/dll/win32/devmgr/lang/id-ID.rc b/dll/win32/devmgr/lang/id-ID.rc index 3f4dc520f77..5c69016780f 100644 --- a/dll/win32/devmgr/lang/id-ID.rc +++ b/dll/win32/devmgr/lang/id-ID.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Untuk melihat rincian tetang file driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Rincian File Driver" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Penyedia:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versi File:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Hak Cipta:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Penanda tangan Digital:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/it-IT.rc b/dll/win32/devmgr/lang/it-IT.rc index f024abf10d9..239ac83a5ec 100644 --- a/dll/win32/devmgr/lang/it-IT.rc +++ b/dll/win32/devmgr/lang/it-IT.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Per vedere i dettagli sui file del driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Dettagli sui file del driver" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Fornitore del Driver:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versione:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Copyright:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Firmatario digitale:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/no-NO.rc b/dll/win32/devmgr/lang/no-NO.rc index a7a5a7b8a66..c46fe017818 100644 --- a/dll/win32/devmgr/lang/no-NO.rc +++ b/dll/win32/devmgr/lang/no-NO.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "For ĺ vise detaljer om driver filene.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Driver fil detaljer" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Produsent:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Filversjon:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Opphavsrett:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Digital signert:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/pl-PL.rc b/dll/win32/devmgr/lang/pl-PL.rc index 59bd6ae2c09..3f71bb18ec4 100644 --- a/dll/win32/devmgr/lang/pl-PL.rc +++ b/dll/win32/devmgr/lang/pl-PL.rc @@ -182,6 +182,28 @@ BEGIN LTEXT "Wyświetla informacje szczegółowe.", -1, 91, 110, 154, 17, SS_NOPREFIX END +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME +CAPTION "Driver File Details" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "", IDC_DEVICON, 7, 7, 20, 20 + LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX + LTEXT "&Driver files:", -1, 7, 36, 204, 8 + CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | + LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 + LTEXT "Provider:", -1, 14, 134, 50, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "File version:", -1, 14, 150, 50, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Copyright:", -1, 14, 166, 50, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digital Signer:", -1, 14, 182, 50, 8 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 +END + IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Szczegóły" diff --git a/dll/win32/devmgr/lang/pt-BR.rc b/dll/win32/devmgr/lang/pt-BR.rc index 5b0c477b2c0..ea9e4cc2938 100644 --- a/dll/win32/devmgr/lang/pt-BR.rc +++ b/dll/win32/devmgr/lang/pt-BR.rc @@ -175,7 +175,7 @@ BEGIN LTEXT "Exibir detalhes sobre os arquivos de driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detalhes sobre os arquivos de driver" FONT 8, "MS Shell Dlg" @@ -187,14 +187,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Fornecedor:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versăo do arquivo:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Direitos autorais:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Signatário digital:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/ro-RO.rc b/dll/win32/devmgr/lang/ro-RO.rc index 4e18c3a212a..b7b578c4e31 100644 --- a/dll/win32/devmgr/lang/ro-RO.rc +++ b/dll/win32/devmgr/lang/ro-RO.rc @@ -1,4 +1,4 @@ -// Romanian language resource file (Petru Dimitriu, 2009-07-15) +// Romanian language resource file (Petru Dimitriu, 2009-07-15) LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL @@ -177,7 +177,7 @@ BEGIN LTEXT "Pentru a vedea detalii despre fi?ierele driver.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detalii fi?iere driver" FONT 8, "MS Shell Dlg" @@ -189,14 +189,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Furnizor:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Versiune fi?ier:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Drept de autor:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Semnatar digital:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/ru-RU.rc b/dll/win32/devmgr/lang/ru-RU.rc index 9a417930515..8c3839826c1 100644 --- a/dll/win32/devmgr/lang/ru-RU.rc +++ b/dll/win32/devmgr/lang/ru-RU.rc @@ -173,7 +173,7 @@ BEGIN LTEXT "Ďđîńěîňđ ńâĺäĺíčé î ôŕéëŕő äđŕéâĺđîâ.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Ńâĺäĺíč˙ î ôŕéëŕő äđŕéâĺđîâ" FONT 8, "MS Shell Dlg" @@ -185,14 +185,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Ďîńňŕâůčę:", -1, 7, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 137, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 137, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Âĺđńč˙ ôŕéëŕ:", -1, 7, 150, 80, 8 - LTEXT "", IDC_FILEVERSION, 137, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 137, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Ŕâňîđńęčĺ ďđŕâŕ:", -1, 7, 166, 112, 8 - LTEXT "", IDC_FILECOPYRIGHT, 137, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 137, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Öčôđîâŕ˙ ďîäďčńü:", -1, 7, 182, 125, 8 - LTEXT "", IDC_DIGITALSIGNER, 137, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 137, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/sk-SK.rc b/dll/win32/devmgr/lang/sk-SK.rc index 7be94acfeb1..ae4f1bebfd7 100644 --- a/dll/win32/devmgr/lang/sk-SK.rc +++ b/dll/win32/devmgr/lang/sk-SK.rc @@ -16,8 +16,8 @@ BEGIN IDS_LOCATIONSTR "Umiestnenie %1!u! (%2)" IDS_DEVCODE " (Kód %1!u!)" IDS_DEVCODE2 " (Kód %2!u!)" - IDS_ENABLEDEVICE "Použiť toto zariadenie (povolené)" - IDS_DISABLEDEVICE "Nepoužiť toto zariadenie (zakázané)" + IDS_ENABLEDEVICE "Používať toto zariadenie (povolené)" + IDS_DISABLEDEVICE "Nepoužívať toto zariadenie (zakázané)" IDS_UNKNOWNDEVICE "Neznáme zariadenie" IDS_NODRIVERLOADED "Pre toto zariadenie nie sú nainštalované žiadne ovládače." IDS_DEVONPARENT "na %1" @@ -166,19 +166,19 @@ FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX - LTEXT "Poskytovateľ ovládača:", -1, 37, 39, 60, 8, SS_NOPREFIX + LTEXT "Sprostredkovateľ:", -1, 34, 39, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVPROVIDER, 100, 39, 146, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY - LTEXT "Dátum ovládača:", -1, 37, 53, 60, 8, SS_NOPREFIX + LTEXT "Dátum ovládača:", -1, 34, 53, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVDATE, 100, 53, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY - LTEXT "Verzia ovládača:", -1, 37, 67, 60, 8, SS_NOPREFIX + LTEXT "Verzia ovládača:", -1, 34, 67, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVVERSION, 100, 67, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY - LTEXT "Digitálne podpísal:", -1, 37, 81, 60, 8, SS_NOPREFIX + LTEXT "Digitálne podpísal:", -1, 34, 81, 60, 8, SS_NOPREFIX EDITTEXT IDC_DIGITALSIGNER, 100, 81, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY PUSHBUTTON "&Driver Details...", IDC_DRIVERDETAILS, 7, 106, 70, 15 LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Detaily o súboroch ovládača" FONT 8, "MS Shell Dlg" @@ -189,15 +189,15 @@ BEGIN CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 - LTEXT "Poskytovateľ:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 - LTEXT "Verzia súboru:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 - LTEXT "Autorské práva:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 - LTEXT "Digitálne podpísal:", -1, 14, 182, 50, 8 //Digital Signer - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + LTEXT "Sprostredkovateľ:", -1, 14, 134, 66, 8 + EDITTEXT IDC_FILEPROVIDER, 80, 134, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Verzia súboru:", -1, 14, 150, 66, 8 + EDITTEXT IDC_FILEVERSION, 80, 150, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Autorské práva:", -1, 14, 166, 66, 8 + EDITTEXT IDC_FILECOPYRIGHT, 80, 166, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digitálne podpísal:", -1, 14, 182, 66, 8 + EDITTEXT IDC_DIGITALSIGNER, 80, 182, 137, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/devmgr/lang/uk-UA.rc b/dll/win32/devmgr/lang/uk-UA.rc index 050e5207fad..2d553038c1b 100644 --- a/dll/win32/devmgr/lang/uk-UA.rc +++ b/dll/win32/devmgr/lang/uk-UA.rc @@ -181,7 +181,7 @@ BEGIN LTEXT "Ďĺđĺăë˙ä âłäîěîńňĺé ďđî ôŕéëč äđŕéâĺđŕ.", -1, 91, 110, 154, 17, SS_NOPREFIX END -IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 250 +IDD_DRIVERDETAILS DIALOGEX DISCARDABLE 0, 0, 224, 230 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME CAPTION "Âłäîěîńňł ďđî ôŕéëč äđŕéâĺđŕ" FONT 8, "MS Shell Dlg" @@ -193,14 +193,14 @@ BEGIN LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 LTEXT "Ďîńňŕ÷ŕëüíčę:", -1, 14, 134, 50, 8 - LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + EDITTEXT IDC_FILEPROVIDER, 66, 134, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Âĺđńł˙ ôŕéëó:", -1, 14, 150, 50, 8 - LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + EDITTEXT IDC_FILEVERSION, 66, 150, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Ŕâňîđńüęł ďđŕâŕ:", -1, 14, 166, 50, 8 - LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + EDITTEXT IDC_FILECOPYRIGHT, 66, 166, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Öčôđîâčé ďłäďčń:", -1, 14, 182, 50, 8 - LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 - PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 + EDITTEXT IDC_DIGITALSIGNER, 66, 182, 155, 8, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + DEFPUSHBUTTON "OK", IDOK, 167, 208, 50, 14 END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 diff --git a/dll/win32/dhcpcsvc/dhcpcsvc.rbuild b/dll/win32/dhcpcsvc/dhcpcsvc.rbuild index 773c295b21c..7afd68b4775 100644 --- a/dll/win32/dhcpcsvc/dhcpcsvc.rbuild +++ b/dll/win32/dhcpcsvc/dhcpcsvc.rbuild @@ -7,6 +7,10 @@ iphlpapi advapi32 oldnames + + + _tzset + adapter.c alloc.c diff --git a/dll/win32/imaadp32.acm/imaadp32.acm.rbuild b/dll/win32/imaadp32.acm/imaadp32.acm.rbuild index f2b04bb6914..073f714f979 100644 --- a/dll/win32/imaadp32.acm/imaadp32.acm.rbuild +++ b/dll/win32/imaadp32.acm/imaadp32.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/dll/win32/inetmib1/inetmib1.rbuild b/dll/win32/inetmib1/inetmib1.rbuild index 77c39b582a1..27079b19c05 100644 --- a/dll/win32/inetmib1/inetmib1.rbuild +++ b/dll/win32/inetmib1/inetmib1.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/dll/win32/iphlpapi/iphlpapi_main.c b/dll/win32/iphlpapi/iphlpapi_main.c index 3fd68560c17..8508d2d416a 100644 --- a/dll/win32/iphlpapi/iphlpapi_main.c +++ b/dll/win32/iphlpapi/iphlpapi_main.c @@ -63,7 +63,6 @@ typedef struct _NAME_SERVER_LIST_CONTEXT { BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - DWORD Version; switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); diff --git a/dll/win32/jscript/dispex.c b/dll/win32/jscript/dispex.c index 6894eae0515..07880bcff5b 100644 --- a/dll/win32/jscript/dispex.c +++ b/dll/win32/jscript/dispex.c @@ -358,6 +358,9 @@ static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, VARIANT *val, { HRESULT hres; + if(prop->flags & PROPF_CONST) + return S_OK; + switch(prop->type) { case PROP_BUILTIN: if(!(prop->flags & PROPF_METHOD)) { @@ -974,6 +977,18 @@ HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, VARIANT *val, js return prop_put(obj, prop, val, ei, caller); } +HRESULT jsdisp_propput_const(DispatchEx *obj, const WCHAR *name, VARIANT *val) +{ + dispex_prop_t *prop; + HRESULT hres; + + hres = ensure_prop_name(obj, name, FALSE, PROPF_ENUM|PROPF_CONST, &prop); + if(FAILED(hres)) + return hres; + + return VariantCopy(&prop->u.var, val); +} + HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { WCHAR buf[12]; diff --git a/dll/win32/jscript/function.c b/dll/win32/jscript/function.c index c7494cfce6c..df46f1d996d 100644 --- a/dll/win32/jscript/function.c +++ b/dll/win32/jscript/function.c @@ -606,7 +606,16 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, if(FAILED(hres)) return hres; - hres = set_prototype(ctx, &function->dispex, prototype); + if(builtin_info) { + VARIANT var; + + V_VT(&var) = VT_I4; + V_I4(&var) = function->length; + hres = jsdisp_propput_const(&function->dispex, lengthW, &var); + } + + if(SUCCEEDED(hres)) + hres = set_prototype(ctx, &function->dispex, prototype); if(FAILED(hres)) { jsdisp_release(&function->dispex); return hres; diff --git a/dll/win32/jscript/global.c b/dll/win32/jscript/global.c index af142ed4db3..92a0cbecd61 100644 --- a/dll/win32/jscript/global.c +++ b/dll/win32/jscript/global.c @@ -550,7 +550,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { LONGLONG d = 0, hlp; - int exp = 0, length; + int exp = 0; VARIANT *arg; WCHAR *str; BSTR val_str = NULL; @@ -569,7 +569,6 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag return hres; str = val_str; - length = SysStringLen(val_str); while(isspaceW(*str)) str++; diff --git a/dll/win32/jscript/jscript.c b/dll/win32/jscript/jscript.c index 9a516aa5d71..c7c77e3aa39 100644 --- a/dll/win32/jscript/jscript.c +++ b/dll/win32/jscript/jscript.c @@ -71,6 +71,7 @@ void script_release(script_ctx_t *ctx) return; jsheap_free(&ctx->tmp_heap); + SysFreeString(ctx->last_match); heap_free(ctx); } diff --git a/dll/win32/jscript/jscript.h b/dll/win32/jscript/jscript.h index c1c8e60f35b..901f25d8b08 100644 --- a/dll/win32/jscript/jscript.h +++ b/dll/win32/jscript/jscript.h @@ -68,6 +68,7 @@ extern HINSTANCE jscript_hinstance; #define PROPF_METHOD 0x0100 #define PROPF_ENUM 0x0200 #define PROPF_CONSTR 0x0400 +#define PROPF_CONST 0x0800 /* NOTE: Keep in sync with names in Object.toString implementation */ typedef enum { @@ -203,6 +204,7 @@ HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServi HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propget(DispatchEx*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_propput_const(DispatchEx*,const WCHAR*,VARIANT*); HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvider*); HRESULT jsdisp_get_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*); @@ -270,6 +272,10 @@ struct _script_ctx_t { IDispatch *host_global; + BSTR last_match; + DWORD last_match_index; + DWORD last_match_length; + DispatchEx *global; DispatchEx *function_constr; DispatchEx *activex_constr; @@ -318,8 +324,9 @@ typedef struct { DWORD len; } match_result_t; -#define REM_CHECK_GLOBAL 0x0001 -#define REM_RESET_INDEX 0x0002 +#define REM_CHECK_GLOBAL 0x0001 +#define REM_RESET_INDEX 0x0002 +#define REM_NO_CTX_UPDATE 0x0004 HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,DWORD,const WCHAR*,DWORD,const WCHAR**,match_result_t**, DWORD*,DWORD*,match_result_t*); HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*); diff --git a/dll/win32/jscript/jscript_Nl.rc b/dll/win32/jscript/jscript_Nl.rc index c4f761a3922..fec11a08000 100644 --- a/dll/win32/jscript/jscript_Nl.rc +++ b/dll/win32/jscript/jscript_Nl.rc @@ -20,10 +20,13 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL +#pragma code_page(65001) + STRINGTABLE DISCARDABLE { IDS_TO_PRIMITIVE "Fout bij het omzetten van het object naar een primitief type" IDS_INVALID_CALL_ARG "Ongeldige procedure-aanroep of argument" + IDS_CREATE_OBJ_ERROR "Automatiseringsserver kan het object niet creĂ«ren" IDS_NO_PROPERTY "Dit object ondersteunt deze eigenschap of methode niet" IDS_ARG_NOT_OPT "Argument is niet optioneel" IDS_SYNTAX_ERROR "Syntax fout" @@ -40,6 +43,7 @@ STRINGTABLE DISCARDABLE IDS_NOT_BOOL "Boolean object verwacht" IDS_JSCRIPT_EXPECTED "JScript object verwacht" IDS_REGEXP_SYNTAX_ERROR "Syntax fout in reguliere expressie" + IDS_URI_INVALID_CHAR "De te coderen URI bevat ongeldige tekens" IDS_INVALID_LENGTH "Array lengte moet een eindig, positief geheel getal zijn" IDS_ARRAY_EXPECTED "Array object verwacht" } diff --git a/dll/win32/jscript/jscript_Si.rc b/dll/win32/jscript/jscript_Si.rc new file mode 100644 index 00000000000..0ddeab117e6 --- /dev/null +++ b/dll/win32/jscript/jscript_Si.rc @@ -0,0 +1,49 @@ +/* + * Copyright 2010 Matej Spindler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "resource.h" + +#pragma code_page(65001) + +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TO_PRIMITIVE "Napaka med spreminjanjem v primitivni tip" + IDS_INVALID_CALL_ARG "NapaÄŤen klic postopka ali argument" + IDS_CREATE_OBJ_ERROR "Avtomatizacijski server ne more ustvariti objekta" + IDS_NO_PROPERTY "Objekt ne podpira atributa ali metode" + IDS_ARG_NOT_OPT "Argument je obvezen" + IDS_SYNTAX_ERROR "NapaÄŤna sintaksa" + IDS_SEMICOLON "PriÄŤakujem ';'" + IDS_LBRACKET "PriÄŤakujem '('" + IDS_RBRACKET "PriÄŤakujem ')'" + IDS_UNTERMINATED_STR "NezakljuÄŤen niz" + IDS_NOT_FUNC "PriÄŤakujem funkcijo" + IDS_NOT_DATE "'[object]' ni date objekt" + IDS_NOT_NUM "PriÄŤakujem število" + IDS_OBJECT_EXPECTED "PriÄŤakujem objekt" + IDS_ILLEGAL_ASSIGN "NapaÄŤna prireditev" + IDS_UNDEFINED "'|' je nedifiniran" + IDS_NOT_BOOL "PriÄŤakujem Boolean objekt" + IDS_JSCRIPT_EXPECTED "PriÄŤakujem JScript objekt" + IDS_REGEXP_SYNTAX_ERROR "NapaÄŤna sintaksa v regularnem izrazu" + IDS_URI_INVALID_CHAR "URI vsebuje neveljavne znake" + IDS_INVALID_LENGTH "DoĹľina polja mora bit pozitivno celo število" + IDS_ARRAY_EXPECTED "PriÄŤakujem Array objekt" +} diff --git a/dll/win32/jscript/regexp.c b/dll/win32/jscript/regexp.c index 7861d229826..fb541891a56 100644 --- a/dll/win32/jscript/regexp.c +++ b/dll/win32/jscript/regexp.c @@ -96,6 +96,12 @@ static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; static const WCHAR execW[] = {'e','x','e','c',0}; static const WCHAR testW[] = {'t','e','s','t',0}; +static const WCHAR leftContextW[] = + {'l','e','f','t','C','o','n','t','e','x','t',0}; +static const WCHAR rightContextW[] = + {'r','i','g','h','t','C','o','n','t','e','x','t',0}; + +static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0}; static const WCHAR emptyW[] = {0}; /* FIXME: Better error handling */ @@ -1977,7 +1983,7 @@ PushBackTrackState(REGlobalData *gData, REOp op, ptrdiff_t btincr = ((char *)result + sz) - ((char *)gData->backTrackStack + btsize); - TRACE("\tBT_Push: %lu,%lu\n", (unsigned long) parenIndex, (unsigned long) parenCount); + TRACE("\tBT_Push: %lu,%lu\n", (ULONG_PTR)parenIndex, (ULONG_PTR)parenCount); JS_COUNT_OPERATION(gData->cx, JSOW_JUMP * (1 + parenCount)); if (btincr > 0) { @@ -2729,7 +2735,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x) case REOP_LPAREN: pc = ReadCompactIndex(pc, &parenIndex); - TRACE("[ %lu ]\n", (unsigned long) parenIndex); + TRACE("[ %lu ]\n", (ULONG_PTR)parenIndex); assert(parenIndex < gData->regexp->parenCount); if (parenIndex + 1 > parenSoFar) parenSoFar = parenIndex + 1; @@ -3093,8 +3099,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x) } TRACE("\tBT_Pop: %ld,%ld\n", - (unsigned long) backTrackData->parenIndex, - (unsigned long) backTrackData->parenCount); + (ULONG_PTR)backTrackData->parenIndex, + (ULONG_PTR)backTrackData->parenCount); continue; } x = result; @@ -3342,8 +3348,6 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D } if(parens) { - DWORD i; - if(regexp->jsregexp->parenCount > *parens_size) { match_result_t *new_parens; @@ -3356,6 +3360,22 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D *parens = new_parens; } + } + + /* FIXME: We often already have a copy of input string that we could use to store last match */ + if(!(rem_flags & REM_NO_CTX_UPDATE) && + (!ctx->last_match || len != SysStringLen(ctx->last_match) || strncmpW(ctx->last_match, str, len))) { + BSTR last_match; + + last_match = SysAllocStringLen(str, len); + if(!last_match) + return E_OUTOFMEMORY; + SysFreeString(ctx->last_match); + ctx->last_match = last_match; + } + + if(parens) { + DWORD i; *parens_cnt = regexp->jsregexp->parenCount; @@ -3376,6 +3396,11 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D ret->len = matchlen; set_last_index(regexp, result->cp-str); + if(!(rem_flags & REM_NO_CTX_UPDATE)) { + ctx->last_match_index = ret->str-str; + ctx->last_match_length = matchlen; + } + return S_OK; } @@ -3712,12 +3737,24 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPP VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { match_result_t match; + VARIANT undef_var; VARIANT_BOOL b; + DWORD argc; HRESULT hres; TRACE("\n"); - hres = run_exec(ctx, jsthis, arg_cnt(dp) ? get_arg(dp,0) : NULL, ei, NULL, &match, NULL, NULL, &b); + argc = arg_cnt(dp); + if(!argc) { + V_VT(&undef_var) = VT_BSTR; + V_BSTR(&undef_var) = SysAllocString(undefinedW); + if(!V_BSTR(&undef_var)) + return E_OUTOFMEMORY; + } + + hres = run_exec(ctx, jsthis, argc ? get_arg(dp,0) : &undef_var, ei, NULL, &match, NULL, NULL, &b); + if(!argc) + SysFreeString(V_BSTR(&undef_var)); if(FAILED(hres)) return hres; @@ -3959,6 +3996,58 @@ HRESULT regexp_string_match(script_ctx_t *ctx, DispatchEx *re, BSTR str, return hres; } +static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, + DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + BSTR ret; + + ret = SysAllocStringLen(ctx->last_match, ctx->last_match_index); + if(!ret) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + } + case DISPATCH_PROPERTYPUT: + return S_OK; + default: + FIXME("unsupported flags\n"); + return E_NOTIMPL; + } + + return S_OK; +} + +static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, + DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + BSTR ret; + + ret = SysAllocString(ctx->last_match+ctx->last_match_index+ctx->last_match_length); + if(!ret) + return E_OUTOFMEMORY; + + V_VT(retv) = VT_BSTR; + V_BSTR(retv) = ret; + } + case DISPATCH_PROPERTYPUT: + return S_OK; + default: + FIXME("unsupported flags\n"); + return E_NOTIMPL; + } + + return S_OK; +} + static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -4019,6 +4108,20 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags return S_OK; } +static const builtin_prop_t RegExpConstr_props[] = { + {leftContextW, RegExpConstr_leftContext, 0}, + {rightContextW, RegExpConstr_rightContext, 0} +}; + +static const builtin_info_t RegExpConstr_info = { + JSCLASS_FUNCTION, + {NULL, Function_value, 0}, + sizeof(RegExpConstr_props)/sizeof(*RegExpConstr_props), + RegExpConstr_props, + NULL, + NULL +}; + HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret) { RegExpInstance *regexp; @@ -4030,7 +4133,7 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di if(FAILED(hres)) return hres; - hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, NULL, + hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, &RegExpConstr_info, PROPF_CONSTR|2, ®exp->dispex, ret); jsdisp_release(®exp->dispex); diff --git a/dll/win32/jscript/rsrc.rc b/dll/win32/jscript/rsrc.rc index d23ea33a2f3..db7e0ff2fa3 100644 --- a/dll/win32/jscript/rsrc.rc +++ b/dll/win32/jscript/rsrc.rc @@ -30,3 +30,4 @@ REGINST REGINST jscript.inf #include "jscript_Nl.rc" #include "jscript_Pt.rc" #include "jscript_Ru.rc" +#include "jscript_Si.rc" diff --git a/dll/win32/jscript/string.c b/dll/win32/jscript/string.c index 510dcc272c6..05b9eba26e1 100644 --- a/dll/win32/jscript/string.c +++ b/dll/win32/jscript/string.c @@ -779,9 +779,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI DWORD parens_cnt = 0, parens_size=0, rep_len=0, length; BSTR rep_str = NULL, match_str = NULL, ret_str, val_str; DispatchEx *rep_func = NULL, *regexp = NULL; - match_result_t *parens = NULL, match, **parens_ptr = &parens; + match_result_t *parens = NULL, match = {NULL,0}, **parens_ptr = &parens; strbuf_t ret = {NULL,0,0}; - DWORD re_flags = 0; + DWORD re_flags = REM_NO_CTX_UPDATE; VARIANT *arg_var; HRESULT hres = S_OK; @@ -860,7 +860,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI if(regexp) { hres = regexp_match_next(ctx, regexp, re_flags, str, length, &cp, parens_ptr, &parens_size, &parens_cnt, &match); - re_flags = REM_CHECK_GLOBAL; + re_flags |= REM_CHECK_GLOBAL; if(hres == S_FALSE) { hres = S_OK; @@ -969,13 +969,28 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI if(rep_func) jsdisp_release(rep_func); - if(regexp) - jsdisp_release(regexp); - SysFreeString(val_str); SysFreeString(rep_str); SysFreeString(match_str); heap_free(parens); + if(SUCCEEDED(hres) && match.str && regexp) { + if(!val_str) + val_str = SysAllocStringLen(str, length); + if(val_str) { + SysFreeString(ctx->last_match); + ctx->last_match = val_str; + val_str = NULL; + ctx->last_match_index = match.str-str; + ctx->last_match_length = match.len; + }else { + hres = E_OUTOFMEMORY; + } + } + + if(regexp) + jsdisp_release(regexp); + SysFreeString(val_str); + if(SUCCEEDED(hres) && retv) { ret_str = SysAllocStringLen(ret.buf, ret.len); if(!ret_str) diff --git a/dll/win32/kernel32/file/file.c b/dll/win32/kernel32/file/file.c index 66046621821..cdbafd08839 100644 --- a/dll/win32/kernel32/file/file.c +++ b/dll/win32/kernel32/file/file.c @@ -1906,7 +1906,8 @@ ReplaceFileW( ) { HANDLE hReplaced = NULL, hReplacement = NULL; - UNICODE_STRING NtReplacedName, NtReplacementName; + UNICODE_STRING NtReplacedName = { 0, 0, NULL }; + UNICODE_STRING NtReplacementName = { 0, 0, NULL }; DWORD Error = ERROR_SUCCESS; NTSTATUS Status; BOOL Ret = FALSE; @@ -2029,8 +2030,10 @@ Cleanup: if (hReplacement) NtClose(hReplacement); if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); - RtlFreeUnicodeString(&NtReplacementName); - RtlFreeUnicodeString(&NtReplacedName); + if (NtReplacementName.Buffer) + RtlFreeHeap(GetProcessHeap(), 0, NtReplacementName.Buffer); + if (NtReplacedName.Buffer) + RtlFreeHeap(GetProcessHeap(), 0, NtReplacedName.Buffer); /* If there was an error, set the error code */ if(!Ret) diff --git a/dll/win32/kernel32/file/find.c b/dll/win32/kernel32/file/find.c index ef2346a598c..df245232e0e 100644 --- a/dll/win32/kernel32/file/find.c +++ b/dll/win32/kernel32/file/find.c @@ -54,7 +54,7 @@ typedef struct _KERNEL32_FIND_DATA_HEADER /* FUNCTIONS ****************************************************************/ -static HANDLE +static VOID InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData, LPCWSTR lpFileName, ULONG DeviceNameInfo) @@ -71,11 +71,9 @@ InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData, RtlCopyMemory(lpFindFileData->cFileName, DeviceName.Buffer, DeviceName.Length); - - return FIND_DEVICE_HANDLE; } -static HANDLE +static VOID InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData, PUNICODE_STRING FileName, ULONG DeviceNameInfo) @@ -101,8 +99,6 @@ InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData, RtlCopyMemory(lpFindFileData->cFileName, BufferA.Buffer, BufferA.Length); - - return FIND_DEVICE_HANDLE; } static VOID diff --git a/dll/win32/kernel32/file/npipe.c b/dll/win32/kernel32/file/npipe.c index d62527e12a5..55aeed952fc 100644 --- a/dll/win32/kernel32/file/npipe.c +++ b/dll/win32/kernel32/file/npipe.c @@ -496,6 +496,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName, if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); + RtlFreeUnicodeString(&NamedPipeName); return FALSE; } @@ -538,9 +539,11 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName, if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); + RtlFreeUnicodeString(&NamedPipeName); return FALSE; } + RtlFreeUnicodeString(&NamedPipeName); return TRUE; } #endif diff --git a/dll/win32/kernel32/include/kernel32.h b/dll/win32/kernel32/include/kernel32.h index 19731210435..59669780806 100755 --- a/dll/win32/kernel32/include/kernel32.h +++ b/dll/win32/kernel32/include/kernel32.h @@ -85,6 +85,8 @@ HANDLE WINAPI OpenConsoleW (LPCWSTR wsName, BOOL bInheritHandle, DWORD dwShareMode); +BOOL WINAPI SetConsoleInputExeNameW(LPCWSTR lpInputExeName); + PTEB GetTeb(VOID); HANDLE FASTCALL TranslateStdHandle(HANDLE hHandle); diff --git a/dll/win32/kernel32/kernel32.pspec b/dll/win32/kernel32/kernel32.pspec index cba32d9f29d..3c09b07cc44 100644 --- a/dll/win32/kernel32/kernel32.pspec +++ b/dll/win32/kernel32/kernel32.pspec @@ -316,6 +316,7 @@ @ stdcall GetConsoleFontInfo(long long long ptr) @ stdcall GetConsoleFontSize(long long) @ stdcall GetConsoleHardwareState(long long ptr) +@ stdcall GetConsoleHistoryInfo(ptr) @ stdcall GetConsoleInputExeNameA(long ptr) @ stdcall GetConsoleInputExeNameW(long ptr) @ stdcall GetConsoleInputWaitHandle() @@ -796,7 +797,6 @@ @ stdcall SetComputerNameW(wstr) @ stdcall SetConsoleActiveScreenBuffer(long) @ stdcall SetConsoleCP(long) -@ stdcall SetConsoleCommandHistoryMode(long) @ stdcall SetConsoleCtrlHandler(ptr long) @ stdcall SetConsoleCursor(long long) @ stdcall SetConsoleCursorInfo(long ptr) @@ -805,6 +805,7 @@ @ stdcall SetConsoleDisplayMode(long long ptr) @ stdcall SetConsoleFont(long long) @ stdcall SetConsoleHardwareState(long long long) +@ stdcall SetConsoleHistoryInfo(ptr) @ stdcall SetConsoleIcon(ptr) @ stdcall SetConsoleInputExeNameA(ptr) @ stdcall SetConsoleInputExeNameW(ptr) diff --git a/dll/win32/kernel32/misc/console.c b/dll/win32/kernel32/misc/console.c index 594b8ac2abb..34b1e84a6aa 100644 --- a/dll/win32/kernel32/misc/console.c +++ b/dll/win32/kernel32/misc/console.c @@ -178,6 +178,37 @@ ConsoleControlDispatcher(DWORD CodeAndFlag) ExitThread(nExitCode); } +/* Get the size needed to copy a string to a capture buffer, including alignment */ +static ULONG +IntStringSize(LPCVOID String, + BOOL Unicode) +{ + ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR); + return (Size + 3) & -4; +} + +/* Copy a string to a capture buffer */ +static VOID +IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer, + LPCVOID String, + BOOL Unicode, + PUNICODE_STRING RequestString) +{ + ULONG Size; + if (Unicode) + { + Size = wcslen(String) * sizeof(WCHAR); + CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)String, Size, (PVOID *)&RequestString->Buffer); + } + else + { + Size = strlen(String); + CsrAllocateMessagePointer(CaptureBuffer, Size * sizeof(WCHAR), (PVOID *)&RequestString->Buffer); + Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR)) + * sizeof(WCHAR); + } + RequestString->Length = RequestString->MaximumLength = Size; +} /* FUNCTIONS *****************************************************************/ @@ -336,29 +367,56 @@ DuplicateConsoleHandle(HANDLE hConsole, } -/* - * @unimplemented (Undocumented) - */ -DWORD -WINAPI -ExpungeConsoleCommandHistoryW(DWORD Unknown0) +static BOOL +IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOL bUnicode) { - DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(EXPUNGE_COMMAND_HISTORY, CSR_CONSOLE); + NTSTATUS Status; + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode)); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.ExpungeCommandHistory.ExeName); + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } +/* + * @implemented (Undocumented) + */ +BOOL +WINAPI +ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName) +{ + return IntExpungeConsoleCommandHistory(lpExeName, TRUE); +} /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ -DWORD +BOOL WINAPI -ExpungeConsoleCommandHistoryA (DWORD Unknown0) +ExpungeConsoleCommandHistoryA(LPCSTR lpExeName) { - DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntExpungeConsoleCommandHistory(lpExeName, FALSE); } @@ -772,61 +830,139 @@ GetConsoleAliasesLengthA(LPSTR lpExeName) } +static DWORD +IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY, CSR_CONSOLE); + NTSTATUS Status; + DWORD HistoryLength = cbHistory * (bUnicode ? 1 : sizeof(WCHAR)); + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) + + HistoryLength); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.GetCommandHistory.ExeName); + Request.Data.GetCommandHistory.Length = HistoryLength; + CsrAllocateMessagePointer(CaptureBuffer, HistoryLength, + (PVOID*)&Request.Data.GetCommandHistory.History); + + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + CsrFreeCaptureBuffer(CaptureBuffer); + SetLastErrorByStatus(Status); + return 0; + } + + if (bUnicode) + { + memcpy(lpHistory, + Request.Data.GetCommandHistory.History, + Request.Data.GetCommandHistory.Length); + } + else + { + WideCharToMultiByte(CP_ACP, 0, + Request.Data.GetCommandHistory.History, + Request.Data.GetCommandHistory.Length / sizeof(WCHAR), + lpHistory, + cbHistory, + NULL, NULL); + } + CsrFreeCaptureBuffer(CaptureBuffer); + return Request.Data.GetCommandHistory.Length; +} + /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryW(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +GetConsoleCommandHistoryW(LPWSTR lpHistory, + DWORD cbHistory, + LPCWSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, TRUE); } - /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryA(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +GetConsoleCommandHistoryA(LPSTR lpHistory, + DWORD cbHistory, + LPCSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, FALSE); } +static DWORD +IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY_LENGTH, CSR_CONSOLE); + NTSTATUS Status; + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode)); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.GetCommandHistoryLength.ExeName); + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return 0; + } + return Request.Data.GetCommandHistoryLength.Length; +} + /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryLengthW(DWORD Unknown0) +GetConsoleCommandHistoryLengthW(LPCWSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistoryLength(lpExeName, TRUE); } - /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ DWORD WINAPI -GetConsoleCommandHistoryLengthA(DWORD Unknown0) +GetConsoleCommandHistoryLengthA(LPCSTR lpExeName) { - DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return IntGetConsoleCommandHistoryLength(lpExeName, FALSE) / sizeof(WCHAR); } + /* * @unimplemented */ @@ -1022,6 +1158,7 @@ OpenConsoleW(LPCWSTR wsName, /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */ Request.Data.GetInputHandleRequest.Access = dwDesiredAccess; Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle; + Request.Data.GetInputHandleRequest.ShareMode = dwShareMode; Status = CsrClientCallServer(&Request, NULL, @@ -1033,20 +1170,7 @@ OpenConsoleW(LPCWSTR wsName, return INVALID_HANDLE_VALUE; } - return Request.Data.GetInputHandleRequest.InputHandle; -} - - -/* - * @unimplemented (Undocumented) - */ -BOOL -WINAPI -SetConsoleCommandHistoryMode(DWORD dwMode) -{ - DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + return Request.Data.GetInputHandleRequest.Handle; } @@ -1175,31 +1299,61 @@ SetConsoleMenuClose(DWORD Unknown0) } -/* - * @unimplemented (Undocumented) - */ -BOOL -WINAPI -SetConsoleNumberOfCommandsA(DWORD Unknown0, - DWORD Unknown1) +static BOOL +IntSetConsoleNumberOfCommands(DWORD dwNumCommands, + LPCVOID lpExeName, + BOOL bUnicode) { - DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(SET_HISTORY_NUMBER_COMMANDS, CSR_CONSOLE); + NTSTATUS Status; + + if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode)); + if (!CaptureBuffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode, + &Request.Data.SetHistoryNumberCommands.ExeName); + Request.Data.SetHistoryNumberCommands.NumCommands = dwNumCommands; + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } - /* - * @unimplemented (Undocumented) + * @implemented (Undocumented) */ BOOL WINAPI -SetConsoleNumberOfCommandsW(DWORD Unknown0, - DWORD Unknown1) +SetConsoleNumberOfCommandsA(DWORD dwNumCommands, + LPCWSTR lpExeName) { - DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE); +} + +/* + * @implemented (Undocumented) + */ +BOOL +WINAPI +SetConsoleNumberOfCommandsW(DWORD dwNumCommands, + LPCSTR lpExeName) +{ + return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE); } @@ -1466,6 +1620,12 @@ IntWriteConsole(HANDLE hConsoleOutput, max(sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes)); + if (Status == STATUS_PENDING) + { + WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE); + CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent); + continue; + } if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, Request); @@ -1559,6 +1719,9 @@ IntReadConsole(HANDLE hConsoleInput, } Request->Status = STATUS_SUCCESS; + Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; + Request->Data.ReadConsoleRequest.Unicode = bUnicode; + Request->Data.ReadConsoleRequest.FullReadSize = (WORD)nNumberOfCharsToRead; CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE); do @@ -1575,10 +1738,7 @@ IntReadConsole(HANDLE hConsoleInput, } } - Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput; - Request->Data.ReadConsoleRequest.Unicode = bUnicode; Request->Data.ReadConsoleRequest.NrCharactersToRead = (WORD)min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize); - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = (WORD)CharsRead; Status = CsrClientCallServer(Request, NULL, @@ -1600,16 +1760,6 @@ IntReadConsole(HANDLE hConsoleInput, Request->Data.ReadConsoleRequest.Buffer, Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize); CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead; - - if (Request->Status == STATUS_NOTIFY_CLEANUP) - { - if(CharsRead > 0) - { - CharsRead--; - nNumberOfCharsToRead++; - } - Request->Status = STATUS_PENDING; - } } while (Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0); @@ -1691,6 +1841,7 @@ AllocConsole(VOID) Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher; Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE; + Request.Data.AllocConsoleRequest.Visible = TRUE; CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE); @@ -3410,6 +3561,64 @@ GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, } +static DWORD +IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode) +{ + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE); + NTSTATUS Status; + + if (nSize == 0) + return 0; + + Request.Data.GetTitleRequest.Length = nSize * (bUnicode ? 1 : sizeof(WCHAR)); + CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.GetTitleRequest.Length); + if (CaptureBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + CsrAllocateMessagePointer(CaptureBuffer, + Request.Data.GetTitleRequest.Length, + (PVOID*)&Request.Data.GetTitleRequest.Title); + + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status))) + { + CsrFreeCaptureBuffer(CaptureBuffer); + SetLastErrorByStatus(Status); + return 0; + } + + if (bUnicode) + { + if (nSize >= sizeof(WCHAR)) + wcscpy((LPWSTR)lpConsoleTitle, Request.Data.GetTitleRequest.Title); + } + else + { + if (nSize < Request.Data.GetTitleRequest.Length / sizeof(WCHAR) || + !WideCharToMultiByte(CP_ACP, // ANSI code page + 0, // performance and mapping flags + Request.Data.GetTitleRequest.Title, // address of wide-character string + -1, // number of characters in string + (LPSTR)lpConsoleTitle, // address of buffer for new string + nSize, // size of buffer + NULL, // FAST + NULL)) + { + /* Yes, if the buffer isn't big enough, it returns 0... Bad API */ + *(LPSTR)lpConsoleTitle = '\0'; + Request.Data.GetTitleRequest.Length = 0; + } + } + CsrFreeCaptureBuffer(CaptureBuffer); + + return Request.Data.GetTitleRequest.Length / sizeof(WCHAR); +} + /*-------------------------------------------------------------- * GetConsoleTitleW * @@ -3420,49 +3629,9 @@ WINAPI GetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); - if (Request == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE); - - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); - if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status))) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - SetLastErrorByStatus(Status); - return 0; - } - - if (nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length) - { - nSize--; - } - else - { - nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR); - } - memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR)); - lpConsoleTitle[nSize] = L'\0'; - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return nSize; + return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE); } - /*-------------------------------------------------------------- * GetConsoleTitleA * @@ -3475,28 +3644,7 @@ WINAPI GetConsoleTitleA(LPSTR lpConsoleTitle, DWORD nSize) { - WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1]; - DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1; - DWORD nWritten; - - if (!lpConsoleTitle || !nSize) return 0; - nWideTitle = GetConsoleTitleW((LPWSTR) WideTitle, nWideTitle); - if (!nWideTitle) return 0; - - if ((nWritten = WideCharToMultiByte(CP_ACP, // ANSI code page - 0, // performance and mapping flags - (LPWSTR) WideTitle, // address of wide-character string - nWideTitle, // number of characters in string - lpConsoleTitle, // address of buffer for new string - nSize - 1, // size of buffer - NULL, // FAST - NULL))) // FAST - { - lpConsoleTitle[nWritten] = '\0'; - return nWritten; - } - - return 0; + return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE); } @@ -3509,41 +3657,33 @@ BOOL WINAPI SetConsoleTitleW(LPCWSTR lpConsoleTitle) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; + CSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + ULONG CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); NTSTATUS Status; - unsigned int c; - Request = RtlAllocateHeap(RtlGetProcessHeap(), 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + - min(wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR))); - if (Request == NULL) + Request.Data.SetTitleRequest.Length = wcslen(lpConsoleTitle) * sizeof(WCHAR); + + CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.SetTitleRequest.Length); + if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); + CsrCaptureMessageBuffer(CaptureBuffer, + (PVOID)lpConsoleTitle, + Request.Data.SetTitleRequest.Length, + (PVOID*)&Request.Data.SetTitleRequest.Title); - for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++) - Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; - - Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR); - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) + Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE)); + CsrFreeCaptureBuffer(CaptureBuffer); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); SetLastErrorByStatus(Status); - return(FALSE); + return FALSE; } - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - return TRUE; } @@ -3559,43 +3699,18 @@ BOOL WINAPI SetConsoleTitleA(LPCSTR lpConsoleTitle) { - PCSR_API_MESSAGE Request; - ULONG CsrRequest; - NTSTATUS Status; - unsigned int c; - - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + - min(strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR))); - if (Request == NULL) + ULONG Length = strlen(lpConsoleTitle) + 1; + LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); + BOOL Ret; + if (!WideTitle) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - - CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE); - - for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++) - Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; - - Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR); - Status = CsrClientCallServer(Request, - NULL, - CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - SetLastErrorByStatus(Status); - return(FALSE); - } - - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - - return TRUE; + MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length); + Ret = SetConsoleTitleW(WideTitle); + HeapFree(GetProcessHeap(), 0, WideTitle); + return Ret; } @@ -3751,7 +3866,8 @@ WINAPI GetConsoleProcessList(LPDWORD lpdwProcessList, DWORD dwProcessCount) { - PCSR_API_MESSAGE Request; + PCSR_CAPTURE_BUFFER CaptureBuffer; + CSR_API_MESSAGE Request; ULONG CsrRequest; ULONG nProcesses; NTSTATUS Status; @@ -3762,43 +3878,38 @@ GetConsoleProcessList(LPDWORD lpdwProcessList, return 0; } - Request = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) - + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD))); - if (Request == NULL) + CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD)); + if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE); - Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)); + Request.Data.GetProcessListRequest.nMaxIds = dwProcessCount; + CsrAllocateMessagePointer(CaptureBuffer, + dwProcessCount * sizeof(DWORD), + (PVOID*)&Request.Data.GetProcessListRequest.ProcessId); - Status = CsrClientCallServer(Request, - NULL, + Status = CsrClientCallServer(&Request, + CaptureBuffer, CsrRequest, - max(sizeof(CSR_API_MESSAGE), - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) - + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD))); - if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status)) + sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); SetLastErrorByStatus (Status); nProcesses = 0; } else { - nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied; + nProcesses = Request.Data.GetProcessListRequest.nProcessIdsTotal; if (dwProcessCount >= nProcesses) { - memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD)); + memcpy(lpdwProcessList, Request.Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD)); } } - RtlFreeHeap(RtlGetProcessHeap(), 0, Request); - + CsrFreeCaptureBuffer(CaptureBuffer); return nProcesses; } @@ -3807,15 +3918,23 @@ GetConsoleProcessList(LPDWORD lpdwProcessList, /*-------------------------------------------------------------- * GetConsoleSelectionInfo * - * @unimplemented + * @implemented */ BOOL WINAPI GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo) { - DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest = MAKE_CSR_API(GET_CONSOLE_SELECTION_INFO, CSR_CONSOLE); + NTSTATUS Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + *lpConsoleSelectionInfo = Request.Data.GetConsoleSelectionInfo.Info; + return TRUE; } @@ -4061,30 +4180,60 @@ GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer) /*-------------------------------------------------------------- * GetConsoleHistoryInfo * - * @unimplemented + * @implemented */ BOOL WINAPI GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo) { - DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE); + NTSTATUS Status; + if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + lpConsoleHistoryInfo->HistoryBufferSize = Request.Data.GetHistoryInfo.HistoryBufferSize; + lpConsoleHistoryInfo->NumberOfHistoryBuffers = Request.Data.GetHistoryInfo.NumberOfHistoryBuffers; + lpConsoleHistoryInfo->dwFlags = Request.Data.GetHistoryInfo.dwFlags; + return TRUE; } /*-------------------------------------------------------------- * SetConsoleHistoryInfo * - * @unimplemented + * @implemented */ BOOL WINAPI SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo) { - DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSR_API_MESSAGE Request; + ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE); + NTSTATUS Status; + if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + Request.Data.SetHistoryInfo.HistoryBufferSize = lpConsoleHistoryInfo->HistoryBufferSize; + Request.Data.SetHistoryInfo.NumberOfHistoryBuffers = lpConsoleHistoryInfo->NumberOfHistoryBuffers; + Request.Data.SetHistoryInfo.dwFlags = lpConsoleHistoryInfo->dwFlags; + Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } diff --git a/dll/win32/kernel32/misc/dllmain.c b/dll/win32/kernel32/misc/dllmain.c index ef47c4d538f..5247b649501 100644 --- a/dll/win32/kernel32/misc/dllmain.c +++ b/dll/win32/kernel32/misc/dllmain.c @@ -130,6 +130,7 @@ BasepInitConsole(VOID) NTSTATUS Status; BOOLEAN NotConsole = FALSE; PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; + LPCWSTR ExeName; WCHAR lpTest[MAX_PATH]; GetModuleFileNameW(NULL, lpTest, MAX_PATH); @@ -150,6 +151,7 @@ BasepInitConsole(VOID) { /* Assume one is needed */ Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE; + Request.Data.AllocConsoleRequest.Visible = TRUE; /* Handle the special flags given to us by BasepInitializeEnvironment */ if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) @@ -168,8 +170,9 @@ BasepInitConsole(VOID) else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW) { /* We'll get the real one soon */ - DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n"); + DPRINT("Creating new invisible console\n"); Parameters->ConsoleHandle = NULL; + Request.Data.AllocConsoleRequest.Visible = FALSE; } else { @@ -181,13 +184,17 @@ BasepInitConsole(VOID) } } - /* Initialize Console Ctrl Handler */ + /* Initialize Console Ctrl Handler and input EXE name */ ConsoleInitialized = TRUE; RtlInitializeCriticalSection(&ConsoleLock); NrAllocatedHandlers = 1; NrCtrlHandlers = 1; CtrlHandlers = InitialHandler; CtrlHandlers[0] = DefaultConsoleCtrlHandler; + + ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\'); + if (ExeName) + SetConsoleInputExeNameW(ExeName + 1); /* Now use the proper console handle */ Request.Data.AllocConsoleRequest.Console = Parameters->ConsoleHandle; diff --git a/dll/win32/mciwave/mciwave.rbuild b/dll/win32/mciwave/mciwave.rbuild index be21c0711ed..69e3c094388 100644 --- a/dll/win32/mciwave/mciwave.rbuild +++ b/dll/win32/mciwave/mciwave.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/dll/win32/msacm32/msacm32.rbuild b/dll/win32/msacm32/msacm32.rbuild index b6f802ee5bb..e32845920d7 100644 --- a/dll/win32/msacm32/msacm32.rbuild +++ b/dll/win32/msacm32/msacm32.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/dll/win32/msadp32.acm/msadp32.acm.rbuild b/dll/win32/msadp32.acm/msadp32.acm.rbuild index 89911f484c5..3dcc1c96085 100644 --- a/dll/win32/msadp32.acm/msadp32.acm.rbuild +++ b/dll/win32/msadp32.acm/msadp32.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/dll/win32/msafd/misc/dllmain.c b/dll/win32/msafd/misc/dllmain.c index c832a856fdd..b0b1f317159 100644 --- a/dll/win32/msafd/misc/dllmain.c +++ b/dll/win32/msafd/misc/dllmain.c @@ -22,8 +22,7 @@ DWORD DebugTraceLevel = 0; HANDLE GlobalHeap; WSPUPCALLTABLE Upcalls; LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest; -ULONG SocketCount = 0; -PSOCKET_INFORMATION *Sockets = NULL; +PSOCKET_INFORMATION SocketListHead = NULL; LIST_ENTRY SockHelpersListHead = { NULL, NULL }; ULONG SockAsyncThreadRefCount; HANDLE SockAsyncHelperAfdHandle; @@ -61,7 +60,7 @@ WSPSocket(int AddressFamily, ULONG SizeOfEA; PAFD_CREATE_PACKET AfdPacket; HANDLE Sock; - PSOCKET_INFORMATION Socket = NULL, PrevSocket = NULL; + PSOCKET_INFORMATION Socket = NULL; PFILE_FULL_EA_INFORMATION EABuffer = NULL; PHELPER_DATA HelperData; PVOID HelperDLLContext; @@ -261,17 +260,6 @@ WSPSocket(int AddressFamily, /* Save Handle */ Socket->Handle = (SOCKET)Sock; - /* XXX See if there's a structure we can reuse -- We need to do this - * more properly. */ - PrevSocket = GetSocketStructure( (SOCKET)Sock ); - - if( PrevSocket ) - { - RtlCopyMemory( PrevSocket, Socket, sizeof(*Socket) ); - RtlFreeHeap( GlobalHeap, 0, Socket ); - Socket = PrevSocket; - } - /* Save Group Info */ if (g != 0) { @@ -292,8 +280,8 @@ WSPSocket(int AddressFamily, NULL); /* Save in Process Sockets List */ - Sockets[SocketCount] = Socket; - SocketCount ++; + Socket->NextSocket = SocketListHead; + SocketListHead = Socket; /* Create the Socket Context */ CreateContext(Socket); @@ -318,79 +306,95 @@ error: return INVALID_SOCKET; } +INT +TranslateNtStatusError(NTSTATUS Status) +{ + switch (Status) + { + case STATUS_CANT_WAIT: + return WSAEWOULDBLOCK; + + case STATUS_TIMEOUT: + return WSAETIMEDOUT; + + case STATUS_SUCCESS: + return NO_ERROR; + + case STATUS_FILE_CLOSED: + case STATUS_END_OF_FILE: + return WSAESHUTDOWN; + + case STATUS_PENDING: + return WSA_IO_PENDING; + + case STATUS_BUFFER_TOO_SMALL: + case STATUS_BUFFER_OVERFLOW: + DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); + return WSAEMSGSIZE; + + case STATUS_NO_MEMORY: + case STATUS_INSUFFICIENT_RESOURCES: + DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); + return WSAENOBUFS; + + case STATUS_INVALID_CONNECTION: + DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); + return WSAEAFNOSUPPORT; + + case STATUS_INVALID_ADDRESS: + DbgPrint("MSAFD: STATUS_INVALID_ADDRESS\n"); + return WSAEADDRNOTAVAIL; + + case STATUS_REMOTE_NOT_LISTENING: + DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); + return WSAECONNREFUSED; + + case STATUS_NETWORK_UNREACHABLE: + DbgPrint("MSAFD: STATUS_NETWORK_UNREACHABLE\n"); + return WSAENETUNREACH; + + case STATUS_INVALID_PARAMETER: + DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); + return WSAEINVAL; + + case STATUS_CANCELLED: + DbgPrint("MSAFD: STATUS_CANCELLED\n"); + return WSA_OPERATION_ABORTED; + + case STATUS_ADDRESS_ALREADY_EXISTS: + DbgPrint("MSAFD: STATUS_ADDRESS_ALREADY_EXISTS\n"); + return WSAEADDRINUSE; + + case STATUS_LOCAL_DISCONNECT: + DbgPrint("MSAFD: STATUS_LOCAL_DISCONNECT\n"); + return WSAECONNABORTED; + + case STATUS_REMOTE_DISCONNECT: + DbgPrint("MSAFD: STATUS_REMOTE_DISCONNECT\n"); + return WSAECONNRESET; + + default: + DbgPrint("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status); + return WSAENETDOWN; + } +} DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes) { - if( ReturnedBytes ) - *ReturnedBytes = 0; - if( Errno ) + *Errno = TranslateNtStatusError(Status); + + if (ReturnedBytes) { - switch (Status) - { - case STATUS_CANT_WAIT: - *Errno = WSAEWOULDBLOCK; - break; - case STATUS_TIMEOUT: - *Errno = WSAETIMEDOUT; - break; - case STATUS_SUCCESS: - /* Return Number of bytes Read */ - if( ReturnedBytes ) - *ReturnedBytes = Received; - break; - case STATUS_FILE_CLOSED: - case STATUS_END_OF_FILE: - *Errno = WSAESHUTDOWN; - break; - case STATUS_PENDING: - *Errno = WSA_IO_PENDING; - break; - case STATUS_BUFFER_TOO_SMALL: - case STATUS_BUFFER_OVERFLOW: - DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); - *Errno = WSAEMSGSIZE; - break; - case STATUS_NO_MEMORY: /* Fall through to STATUS_INSUFFICIENT_RESOURCES */ - case STATUS_INSUFFICIENT_RESOURCES: - DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); - *Errno = WSAENOBUFS; - break; - case STATUS_INVALID_CONNECTION: - DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); - *Errno = WSAEAFNOSUPPORT; - break; - case STATUS_INVALID_ADDRESS: - DbgPrint("MSAFD: STATUS_INVALID_ADDRESS\n"); - *Errno = WSAEADDRNOTAVAIL; - break; - case STATUS_REMOTE_NOT_LISTENING: - DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); - *Errno = WSAECONNREFUSED; - break; - case STATUS_NETWORK_UNREACHABLE: - DbgPrint("MSAFD: STATUS_NETWORK_UNREACHABLE\n"); - *Errno = WSAENETUNREACH; - break; - case STATUS_INVALID_PARAMETER: - DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); - *Errno = WSAEINVAL; - break; - case STATUS_CANCELLED: - DbgPrint("MSAFD: STATUS_CANCELLED\n"); - *Errno = WSA_OPERATION_ABORTED; - break; - default: - DbgPrint("MSAFD: Error %x is unknown\n", Status); - *Errno = WSAEINVAL; - break; - } + if (!*Errno) + *ReturnedBytes = Received; + else + *ReturnedBytes = 0; } - /* Success */ - return Status == STATUS_SUCCESS ? 0 : SOCKET_ERROR; + return *Errno ? SOCKET_ERROR : 0; } /* @@ -407,7 +411,7 @@ WSPCloseSocket(IN SOCKET Handle, OUT LPINT lpErrno) { IO_STATUS_BLOCK IoStatusBlock; - PSOCKET_INFORMATION Socket = NULL; + PSOCKET_INFORMATION Socket = NULL, CurrentSocket; NTSTATUS Status; HANDLE SockEvent; AFD_DISCONNECT_INFO DisconnectInfo; @@ -425,6 +429,12 @@ WSPCloseSocket(IN SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } if (Socket->HelperEvents & WSH_NOTIFY_CLOSE) { @@ -546,11 +556,32 @@ WSPCloseSocket(IN SOCKET Handle, NtClose(Socket->TdiConnectionHandle); Socket->TdiConnectionHandle = NULL; + if (SocketListHead == Socket) + { + SocketListHead = SocketListHead->NextSocket; + } + else + { + CurrentSocket = SocketListHead; + while (CurrentSocket->NextSocket) + { + if (CurrentSocket->NextSocket == Socket) + { + CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket; + break; + } + + CurrentSocket = CurrentSocket->NextSocket; + } + } + + HeapFree(GlobalHeap, 0, Socket); + /* Close the handle */ NtClose((HANDLE)Handle); NtClose(SockEvent); - return NO_ERROR; + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); } @@ -599,6 +630,12 @@ WSPBind(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + HeapFree(GlobalHeap, 0, BindData); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Set up Address in TDI Format */ BindData->Address.TAAddressCount = 1; @@ -650,13 +687,17 @@ WSPBind(SOCKET Handle, Status = IOSB.Status; } + NtClose( SockEvent ); + HeapFree(GlobalHeap, 0, BindData); + + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); + /* Set up Socket Data */ Socket->SharedData.State = SocketBound; Socket->TdiAddressHandle = (HANDLE)IOSB.Information; - NtClose( SockEvent ); - HeapFree(GlobalHeap, 0, BindData); - if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_BIND)) + if (Socket->HelperEvents & WSH_NOTIFY_BIND) { Status = Socket->HelperData->WSHNotify(Socket->HelperContext, Socket->Handle, @@ -688,6 +729,11 @@ WSPListen(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } if (Socket->SharedData.Listening) return 0; @@ -723,14 +769,17 @@ WSPListen(SOCKET Handle, { WaitForSingleObject(SockEvent, INFINITE); Status = IOSB.Status; - } + } + + NtClose( SockEvent ); + + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); /* Set to Listening */ Socket->SharedData.Listening = TRUE; - NtClose( SockEvent ); - - if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_LISTEN)) + if (Socket->HelperEvents & WSH_NOTIFY_LISTEN) { Status = Socket->HelperData->WSHNotify(Socket->HelperContext, Socket->Handle, @@ -891,6 +940,7 @@ WSPSelect(IN int nfds, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } /* Clear the Structures */ @@ -1028,6 +1078,12 @@ WSPAccept(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return INVALID_SOCKET; + } /* If this is non-blocking, make sure there's something for us to accept */ FD_ZERO(&ReadSet); @@ -1035,12 +1091,17 @@ WSPAccept(SOCKET Handle, Timeout.tv_sec=0; Timeout.tv_usec=0; - WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL); + if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR) + { + NtClose(SockEvent); + return INVALID_SOCKET; + } if (ReadSet.fd_array[0] != Socket->Handle) { NtClose(SockEvent); - return 0; + *lpErrno = WSAEWOULDBLOCK; + return INVALID_SOCKET; } /* Send IOCTL */ @@ -1278,7 +1339,9 @@ WSPAccept(SOCKET Handle, &ProtocolInfo, GroupID, Socket->SharedData.CreateFlags, - NULL); + lpErrno); + if (AcceptSocket == INVALID_SOCKET) + return INVALID_SOCKET; /* Set up the Accept Structure */ AcceptData.ListenHandle = (HANDLE)AcceptSocket; @@ -1384,6 +1447,12 @@ WSPConnect(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Bind us First */ if (Socket->SharedData.State == SocketOpen) @@ -1400,7 +1469,8 @@ WSPConnect(SOCKET Handle, BindAddress, &BindAddressLength); /* Bind it */ - WSPBind(Handle, BindAddress, BindAddressLength, NULL); + if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR) + return INVALID_SOCKET; } /* Set the Connect Data */ @@ -1423,6 +1493,9 @@ WSPConnect(SOCKET Handle, WaitForSingleObject(SockEvent, INFINITE); Status = IOSB.Status; } + + if (Status != STATUS_SUCCESS) + goto notify; } /* Dynamic Structure...ugh */ @@ -1468,6 +1541,9 @@ WSPConnect(SOCKET Handle, WaitForSingleObject(SockEvent, INFINITE); Status = IOSB.Status; } + + if (Status != STATUS_SUCCESS) + goto notify; } /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */ @@ -1499,6 +1575,9 @@ WSPConnect(SOCKET Handle, Status = IOSB.Status; } + if (Status != STATUS_SUCCESS) + goto notify; + Socket->TdiConnectionHandle = (HANDLE)IOSB.Information; /* Get any pending connect data */ @@ -1522,14 +1601,15 @@ WSPConnect(SOCKET Handle, } } + AFD_DbgPrint(MID_TRACE,("Ending\n")); + +notify: /* Re-enable Async Event */ SockReenableAsyncSelectEvent(Socket, FD_WRITE); /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */ SockReenableAsyncSelectEvent(Socket, FD_CONNECT); - AFD_DbgPrint(MID_TRACE,("Ending\n")); - NtClose( SockEvent ); if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_CONNECT)) @@ -1589,6 +1669,12 @@ WSPShutdown(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Set AFD Disconnect Type */ switch (HowTo) @@ -1663,6 +1749,12 @@ WSPGetSockName(IN SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Allocate a buffer for the address */ TdiAddressSize = @@ -1751,6 +1843,12 @@ WSPGetPeerName(IN SOCKET s, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(s); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Allocate a buffer for the address */ TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + *NameLength; @@ -1828,6 +1926,11 @@ WSPIoctl(IN SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } switch( dwIoControlCode ) { @@ -2122,8 +2225,12 @@ GetSocketInformation(PSOCKET_INFORMATION Socket, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } + if (Status != STATUS_SUCCESS) + return -1; + /* Return Information */ if (Ulong != NULL) { @@ -2193,27 +2300,30 @@ SetSocketInformation(PSOCKET_INFORMATION Socket, if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } NtClose( SockEvent ); - return 0; + return Status == STATUS_SUCCESS ? 0 : -1; } PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle) { - ULONG i; + PSOCKET_INFORMATION CurrentSocket; - for (i=0; iHandle == Handle) - { - return Sockets[i]; - } + if (CurrentSocket->Handle == Handle) + return CurrentSocket; + + CurrentSocket = CurrentSocket->NextSocket; } - return 0; + + return NULL; } int CreateContext(PSOCKET_INFORMATION Socket) @@ -2258,11 +2368,12 @@ int CreateContext(PSOCKET_INFORMATION Socket) if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } NtClose( SockEvent ); - return 0; + return Status == STATUS_SUCCESS ? 0 : -1; } BOOLEAN SockCreateOrReferenceAsyncThread(VOID) @@ -2730,10 +2841,6 @@ DllMain(HANDLE hInstDll, /* Heap to use when allocating */ GlobalHeap = GetProcessHeap(); - /* Allocate Heap for 1024 Sockets, can be expanded later */ - Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024); - if (!Sockets) return FALSE; - AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n")); break; diff --git a/dll/win32/msafd/misc/event.c b/dll/win32/msafd/misc/event.c index 9a49e31b282..a1dc8766148 100644 --- a/dll/win32/msafd/misc/event.c +++ b/dll/win32/msafd/misc/event.c @@ -36,6 +36,12 @@ WSPEventSelect( /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Set Socket to Non-Blocking */ BlockMode = 1; @@ -104,12 +110,16 @@ WSPEventSelect( /* Wait for return */ if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); + Status = IOSB.Status; } AFD_DbgPrint(MID_TRACE,("Waited\n")); NtClose( SockEvent ); + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); + AFD_DbgPrint(MID_TRACE,("Closed event\n")); /* Set Socket Data*/ @@ -148,6 +158,12 @@ WSPEnumNetworkEvents( /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + NtClose(SockEvent); + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } EnumReq.Event = hEventObject; @@ -168,13 +184,16 @@ WSPEnumNetworkEvents( /* Wait for return */ if (Status == STATUS_PENDING) { WaitForSingleObject(SockEvent, INFINITE); - Status = STATUS_SUCCESS; + Status = IOSB.Status; } AFD_DbgPrint(MID_TRACE,("Waited\n")); NtClose( SockEvent ); + if (Status != STATUS_SUCCESS) + return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); + AFD_DbgPrint(MID_TRACE,("Closed event\n")); AFD_DbgPrint(MID_TRACE,("About to touch struct at %x (%d)\n", lpNetworkEvents, sizeof(*lpNetworkEvents))); @@ -186,44 +205,49 @@ WSPEnumNetworkEvents( /* Set Events to wait for */ if (EnumReq.PollEvents & AFD_EVENT_RECEIVE) { lpNetworkEvents->lNetworkEvents |= FD_READ; + lpNetworkEvents->iErrorCode[FD_READ_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_READ_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_SEND) { lpNetworkEvents->lNetworkEvents |= FD_WRITE; + lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_WRITE_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_OOB_RECEIVE) { lpNetworkEvents->lNetworkEvents |= FD_OOB; + lpNetworkEvents->iErrorCode[FD_OOB_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_OOB_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_ACCEPT) { lpNetworkEvents->lNetworkEvents |= FD_ACCEPT; + lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_ACCEPT_BIT]); } if (EnumReq.PollEvents & (AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL)) { lpNetworkEvents->lNetworkEvents |= FD_CONNECT; + lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CONNECT_BIT]); } if (EnumReq.PollEvents & (AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE)) { lpNetworkEvents->lNetworkEvents |= FD_CLOSE; + lpNetworkEvents->iErrorCode[FD_CLOSE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CLOSE_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_QOS) { lpNetworkEvents->lNetworkEvents |= FD_QOS; + lpNetworkEvents->iErrorCode[FD_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_QOS_BIT]); } if (EnumReq.PollEvents & AFD_EVENT_GROUP_QOS) { lpNetworkEvents->lNetworkEvents |= FD_GROUP_QOS; + lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_GROUP_QOS_BIT]); } - if( NT_SUCCESS(Status) ) *lpErrno = 0; - else *lpErrno = WSAEINVAL; - AFD_DbgPrint(MID_TRACE,("Leaving\n")); - return 0; + return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, NULL); } /* EOF */ diff --git a/dll/win32/msafd/misc/sndrcv.c b/dll/win32/msafd/misc/sndrcv.c index 212b4fc25ca..557fdae910e 100644 --- a/dll/win32/msafd/misc/sndrcv.c +++ b/dll/win32/msafd/misc/sndrcv.c @@ -29,6 +29,11 @@ WSPAsyncSelect(IN SOCKET Handle, /* Get the Socket Structure associated to this Socket */ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Allocate the Async Data Structure to pass on to the Thread later */ AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); @@ -46,7 +51,11 @@ WSPAsyncSelect(IN SOCKET Handle, /* Deactive WSPEventSelect */ if (Socket->SharedData.AsyncEvents) { - WSPEventSelect(Handle, NULL, 0, NULL); + if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR) + { + HeapFree(GetProcessHeap(), 0, AsyncData); + return SOCKET_ERROR; + } } /* Create the Asynch Thread if Needed */ @@ -111,6 +120,11 @@ WSPRecv(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); @@ -182,7 +196,7 @@ WSPRecv(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -223,7 +237,7 @@ WSPRecv(SOCKET Handle, } /* Re-enable Async Event */ - if (*ReceiveFlags == MSG_OOB) + if (*ReceiveFlags & MSG_OOB) { SockReenableAsyncSelectEvent(Socket, FD_OOB); } @@ -261,6 +275,11 @@ WSPRecvFrom(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); @@ -334,7 +353,7 @@ WSPRecvFrom(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -399,6 +418,11 @@ WSPSend(SOCKET Handle, /* Get the Socket Structure associate to this Socket*/ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, NULL, 1, FALSE ); @@ -461,7 +485,7 @@ WSPSend(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -483,7 +507,7 @@ WSPSend(SOCKET Handle, if (Status == STATUS_PENDING) { AFD_DbgPrint(MID_TRACE,("Leaving (Pending)\n")); - return WSA_IO_PENDING; + return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); } /* Re-enable Async Event */ @@ -523,6 +547,11 @@ WSPSendTo(SOCKET Handle, /* Get the Socket Structure associate to this Socket */ Socket = GetSocketStructure(Handle); + if (!Socket) + { + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; + } /* Bind us First */ if (Socket->SharedData.State == SocketOpen) @@ -540,7 +569,8 @@ WSPSendTo(SOCKET Handle, BindAddress, &BindAddressLength); /* Bind it */ - WSPBind(Handle, BindAddress, BindAddressLength, NULL); + if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR) + return SOCKET_ERROR; } RemoteAddress = HeapAlloc(GlobalHeap, 0, 0x6 + SocketAddressLength); @@ -612,7 +642,7 @@ WSPSendTo(SOCKET Handle, /* Send IOCTL */ Status = NtDeviceIoControlFile((HANDLE)Handle, - Event ? Event : SockEvent, + Event, APCFunction, APCContext, IOSB, @@ -637,11 +667,8 @@ WSPSendTo(SOCKET Handle, HeapFree(GlobalHeap, 0, BindAddress); } - if (Status == STATUS_PENDING) - return WSA_IO_PENDING; - - /* Re-enable Async Event */ - SockReenableAsyncSelectEvent(Socket, FD_WRITE); + if (Status != STATUS_PENDING) + SockReenableAsyncSelectEvent(Socket, FD_WRITE); return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); } diff --git a/dll/win32/msafd/msafd.h b/dll/win32/msafd/msafd.h index d0423b71ee6..f5795152f12 100755 --- a/dll/win32/msafd/msafd.h +++ b/dll/win32/msafd/msafd.h @@ -100,6 +100,7 @@ typedef struct _SOCKET_INFORMATION { BOOL TrySAN; SOCKADDR WSLocalAddress; SOCKADDR WSRemoteAddress; + struct _SOCKET_INFORMATION *NextSocket; } SOCKET_INFORMATION, *PSOCKET_INFORMATION; @@ -409,6 +410,8 @@ PSOCKET_INFORMATION GetSocketStructure( SOCKET Handle ); +INT TranslateNtStatusError( NTSTATUS Status ); + VOID DeleteSocketStructure( SOCKET Handle ); int GetSocketInformation( diff --git a/dll/win32/msg711.acm/msg711.acm.rbuild b/dll/win32/msg711.acm/msg711.acm.rbuild index 468d9927b2f..88e87f98add 100644 --- a/dll/win32/msg711.acm/msg711.acm.rbuild +++ b/dll/win32/msg711.acm/msg711.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/dll/win32/mshtml/Nl.rc b/dll/win32/mshtml/Nl.rc index 33baf39b518..d32980ba9fb 100644 --- a/dll/win32/mshtml/Nl.rc +++ b/dll/win32/mshtml/Nl.rc @@ -35,9 +35,9 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Wine-Gecko-Installatie" FONT 8, "MS Shell Dlg" { - LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ - "to work correctly. Wine can automatically download and install it for you.\n\n" \ - "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + LTEXT "Wine kon geen Gecko pakket vinden. Gecko is nodig voor programma's die gebruik maken " \ + "van embedded HTML. Wine kan het automatisch voor u downloaden en installeren.\n\n" \ + "Noot: het is aanbevolen om distro pakketten te gebruiken. Zie http://wiki.winehq.org/Gecko voor details.", ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Voortgang", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Installeren", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/dll/win32/mshtml/Ru.rc b/dll/win32/mshtml/Ru.rc index 8d3a4c3cc0a..6722ddc5dfc 100644 --- a/dll/win32/mshtml/Ru.rc +++ b/dll/win32/mshtml/Ru.rc @@ -36,10 +36,12 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "ĐŁŃтановка Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Wine не может найти пакет Gecko который Đ˝Ńжен для приложений ŃĐľ вŃтроенным HTML " \ - "для корректной работы. Wine может автоматичеŃки загрŃзить и ŃŃтановить его для ВаŃ.\n\n" \ - "Примечание: Рекомендовано иŃпользовать пакет из ВаŃего диŃтрибŃтива. ПоŃетите http://wiki.winehq.org/Gecko для деталей.", - ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT + LTEXT "Wine не может найти пакет Gecko, который необходим для корректной работы приложений"\ + "Ń ĐżĐľĐ´Đ´ĐµŃ€Đ¶ĐşĐľĐą HTML. " \ + "Wine может автоматичеŃки загрŃзить и ŃŃтановить его для ваŃ.\n\n" \ + "Примечание: рекомендŃетŃŃŹ иŃпользовать пакет, предоŃтавляемый ваŃим диŃтрибŃтивом. "\ + "ПоŃетите http://wiki.winehq.org/Gecko для полŃчения более подробной информации.", + ID_DWL_STATUS, 10, 10, 240, 70, SS_LEFT CONTROL "ПрогреŃŃ", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 65, 240, 12 DEFPUSHBUTTON "&ĐŁŃтановить", ID_DWL_INSTALL, 180, 85, 70, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Отмена", IDCANCEL, 100, 85, 70, 15, WS_GROUP | WS_TABSTOP diff --git a/dll/win32/mshtml/htmlbody.c b/dll/win32/mshtml/htmlbody.c index 5c66e65a44a..18a60418cee 100644 --- a/dll/win32/mshtml/htmlbody.c +++ b/dll/win32/mshtml/htmlbody.c @@ -434,6 +434,10 @@ static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text); nsAString_Finish(&text); + if(NS_FAILED(nsres)) { + ERR("SetText failed: %08x\n", nsres); + return E_FAIL; + } return S_OK; } @@ -462,7 +466,7 @@ static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT nsAString_Finish(&text); - return S_OK; + return hres; } static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v) diff --git a/dll/win32/mshtml/htmldoc.c b/dll/win32/mshtml/htmldoc.c index 12aa8c002dc..61476328dd1 100644 --- a/dll/win32/mshtml/htmldoc.c +++ b/dll/win32/mshtml/htmldoc.c @@ -889,8 +889,25 @@ static HRESULT WINAPI HTMLDocument_close(IHTMLDocument2 *iface) static HRESULT WINAPI HTMLDocument_clear(IHTMLDocument2 *iface) { HTMLDocument *This = HTMLDOC_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + nsIDOMNSHTMLDocument *nsdoc; + nsresult nsres; + + TRACE("(%p)\n", This); + + nsres = nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nsdoc); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMNSHTMLDocument iface: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMNSHTMLDocument_Clear(nsdoc); + nsIDOMNSHTMLDocument_Release(nsdoc); + if(NS_FAILED(nsres)) { + ERR("Clear failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLDocument_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID, diff --git a/dll/win32/mshtml/htmldoc3.c b/dll/win32/mshtml/htmldoc3.c index e28297fce14..f4ea0962cee 100644 --- a/dll/win32/mshtml/htmldoc3.c +++ b/dll/win32/mshtml/htmldoc3.c @@ -308,15 +308,19 @@ static HRESULT WINAPI HTMLDocument3_get_dir(IHTMLDocument3 *iface, BSTR *p) static HRESULT WINAPI HTMLDocument3_put_oncontextmenu(IHTMLDocument3 *iface, VARIANT v) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; + + TRACE("(%p)->()\n", This); + + return set_doc_event(This, EVENTID_CONTEXTMENU, &v); } static HRESULT WINAPI HTMLDocument3_get_oncontextmenu(IHTMLDocument3 *iface, VARIANT *p) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_doc_event(This, EVENTID_CONTEXTMENU, p); } static HRESULT WINAPI HTMLDocument3_put_onstop(IHTMLDocument3 *iface, VARIANT v) diff --git a/dll/win32/mshtml/htmlelem.c b/dll/win32/mshtml/htmlelem.c index b0cb791a1e8..5bf29159aed 100644 --- a/dll/win32/mshtml/htmlelem.c +++ b/dll/win32/mshtml/htmlelem.c @@ -1803,13 +1803,11 @@ static HRESULT WINAPI HTMLFiltersCollection_get_length(IHTMLFiltersCollection *i { HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + if(!p) + return E_POINTER; + FIXME("(%p)->(%p) Always returning 0\n", This, p); - - if(!p) - return E_POINTER; - - if(p) - *p = 0; + *p = 0; return S_OK; } diff --git a/dll/win32/mshtml/htmlevent.c b/dll/win32/mshtml/htmlevent.c index eef006c962c..6925a0cf2ac 100644 --- a/dll/win32/mshtml/htmlevent.c +++ b/dll/win32/mshtml/htmlevent.c @@ -56,6 +56,9 @@ static const WCHAR onchangeW[] = {'o','n','c','h','a','n','g','e',0}; static const WCHAR clickW[] = {'c','l','i','c','k',0}; static const WCHAR onclickW[] = {'o','n','c','l','i','c','k',0}; +static const WCHAR contextmenuW[] = {'c','o','n','t','e','x','t','m','e','n','u',0}; +static const WCHAR oncontextmenuW[] = {'o','n','c','o','n','t','e','x','t','m','e','n','u',0}; + static const WCHAR dblclickW[] = {'d','b','l','c','l','i','c','k',0}; static const WCHAR ondblclickW[] = {'o','n','d','b','l','c','l','i','c','k',0}; @@ -141,6 +144,8 @@ static const event_info_t event_info[] = { EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {clickW, onclickW, EVENTT_MOUSE, DISPID_EVMETH_ONCLICK, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {contextmenuW, oncontextmenuW, EVENTT_MOUSE, DISPID_EVMETH_ONCONTEXTMENU, + EVENT_BUBBLE}, {dblclickW, ondblclickW, EVENTT_MOUSE, DISPID_EVMETH_ONDBLCLICK, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {dragW, ondragW, EVENTT_MOUSE, DISPID_EVMETH_ONDRAG, @@ -283,16 +288,14 @@ static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface) static HRESULT WINAPI HTMLEventObj_GetTypeInfoCount(IHTMLEventObj *iface, UINT *pctinfo) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); } static HRESULT WINAPI HTMLEventObj_GetTypeInfo(IHTMLEventObj *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLEventObj_GetIDsOfNames(IHTMLEventObj *iface, REFIID riid, @@ -300,9 +303,7 @@ static HRESULT WINAPI HTMLEventObj_GetIDsOfNames(IHTMLEventObj *iface, REFIID ri LCID lcid, DISPID *rgDispId) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLEventObj_Invoke(IHTMLEventObj *iface, DISPID dispIdMember, @@ -310,9 +311,8 @@ static HRESULT WINAPI HTMLEventObj_Invoke(IHTMLEventObj *iface, DISPID dispIdMem VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLElement **p) diff --git a/dll/win32/mshtml/htmlevent.h b/dll/win32/mshtml/htmlevent.h index 6ba2fe29dc7..3a8619a068f 100644 --- a/dll/win32/mshtml/htmlevent.h +++ b/dll/win32/mshtml/htmlevent.h @@ -21,6 +21,7 @@ typedef enum { EVENTID_BLUR, EVENTID_CHANGE, EVENTID_CLICK, + EVENTID_CONTEXTMENU, EVENTID_DBLCLICK, EVENTID_DRAG, EVENTID_DRAGSTART, diff --git a/dll/win32/mshtml/htmlform.c b/dll/win32/mshtml/htmlform.c index 68860560148..8e169170a4b 100644 --- a/dll/win32/mshtml/htmlform.c +++ b/dll/win32/mshtml/htmlform.c @@ -41,6 +41,41 @@ struct HTMLFormElement { #define HTMLFORM(x) (&(x)->lpHTMLFormElementVtbl) +static HRESULT htmlform_item(HTMLFormElement *This, int i, IDispatch **ret) +{ + nsIDOMHTMLCollection *elements; + nsIDOMNode *item; + HTMLDOMNode *node; + nsresult nsres; + + nsres = nsIDOMHTMLFormElement_GetElements(This->nsform, &elements); + if(NS_FAILED(nsres)) { + FIXME("GetElements failed: 0x%08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMHTMLCollection_Item(elements, i, &item); + nsIDOMHTMLCollection_Release(elements); + if(NS_FAILED(nsres)) { + FIXME("Item failed: 0x%08x\n", nsres); + return E_FAIL; + } + + if(item) { + node = get_node(This->element.node.doc, item, TRUE); + if(!node) + return E_OUTOFMEMORY; + + IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); + nsIDOMNode_Release(item); + *ret = (IDispatch*)HTMLDOMNODE(node); + }else { + *ret = NULL; + } + + return S_OK; +} + #define HTMLFORM_THIS(iface) DEFINE_THIS(HTMLFormElement, HTMLFormElement, iface) static HRESULT WINAPI HTMLFormElement_QueryInterface(IHTMLFormElement *iface, @@ -98,15 +133,43 @@ static HRESULT WINAPI HTMLFormElement_Invoke(IHTMLFormElement *iface, DISPID dis static HRESULT WINAPI HTMLFormElement_put_action(IHTMLFormElement *iface, BSTR v) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(%s)\n", This, wine_dbgstr_w(v)); - return E_NOTIMPL; + nsAString action_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, wine_dbgstr_w(v)); + + nsAString_InitDepend(&action_str, v); + nsres = nsIDOMHTMLFormElement_SetAction(This->nsform, &action_str); + nsAString_Finish(&action_str); + if(NS_FAILED(nsres)) { + ERR("SetAction failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLFormElement_get_action(IHTMLFormElement *iface, BSTR *p) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString action_str; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&action_str, NULL); + nsres = nsIDOMHTMLFormElement_GetAction(This->nsform, &action_str); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *action; + nsAString_GetData(&action_str, &action); + hres = nsuri_to_url(action, FALSE, p); + }else { + ERR("GetAction failed: %08x\n", nsres); + hres = E_FAIL; + } + + return hres; } static HRESULT WINAPI HTMLFormElement_put_dir(IHTMLFormElement *iface, BSTR v) @@ -238,8 +301,19 @@ static HRESULT WINAPI HTMLFormElement_put_length(IHTMLFormElement *iface, LONG v static HRESULT WINAPI HTMLFormElement_get_length(IHTMLFormElement *iface, LONG *p) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRInt32 length; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLFormElement_GetLength(This->nsform, &length); + if(NS_FAILED(nsres)) { + ERR("GetLength failed: %08x\n", nsres); + return E_FAIL; + } + + *p = length; + return S_OK; } static HRESULT WINAPI HTMLFormElement__newEnum(IHTMLFormElement *iface, IUnknown **p) @@ -253,7 +327,20 @@ static HRESULT WINAPI HTMLFormElement_item(IHTMLFormElement *iface, VARIANT name VARIANT index, IDispatch **pdisp) { HTMLFormElement *This = HTMLFORM_THIS(iface); - FIXME("(%p)->(v v %p)\n", This, pdisp); + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); + + if(!pdisp) + return E_INVALIDARG; + *pdisp = NULL; + + if(V_VT(&name) == VT_I4) { + if(V_I4(&name) < 0) + return E_INVALIDARG; + return htmlform_item(This, V_I4(&name), pdisp); + } + + FIXME("Unsupported args\n"); return E_NOTIMPL; } @@ -428,34 +515,21 @@ static HRESULT HTMLFormElement_invoke(HTMLDOMNode *iface, EXCEPINFO *ei, IServiceProvider *caller) { HTMLFormElement *This = HTMLFORM_NODE_THIS(iface); - nsIDOMHTMLCollection *elements; - nsIDOMNode *item; - HTMLDOMNode *node; - nsresult nsres; + IDispatch *ret; + HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); - nsres = nsIDOMHTMLFormElement_GetElements(This->nsform, &elements); - if(NS_FAILED(nsres)) { - FIXME("GetElements failed: 0x%08x\n", nsres); - return E_FAIL; + hres = htmlform_item(This, id - MSHTML_DISPID_CUSTOM_MIN, &ret); + if(FAILED(hres)) + return hres; + + if(ret) { + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = ret; + }else { + V_VT(res) = VT_NULL; } - - nsres = nsIDOMHTMLCollection_Item(elements, id - MSHTML_DISPID_CUSTOM_MIN, &item); - nsIDOMHTMLCollection_Release(elements); - if(NS_FAILED(nsres)) { - FIXME("Item failed: 0x%08x\n", nsres); - return E_FAIL; - } - - node = get_node(This->element.node.doc, item, TRUE); - - V_VT(res) = VT_DISPATCH; - V_DISPATCH(res) = (IDispatch*)node; - - IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); - nsIDOMNode_Release(item); - return S_OK; } diff --git a/dll/win32/mshtml/htmlinput.c b/dll/win32/mshtml/htmlinput.c index 1b8d1c5413f..76a5063bc2e 100644 --- a/dll/win32/mshtml/htmlinput.c +++ b/dll/win32/mshtml/htmlinput.c @@ -106,8 +106,24 @@ static HRESULT WINAPI HTMLInputElement_Invoke(IHTMLInputElement *iface, DISPID d static HRESULT WINAPI HTMLInputElement_put_type(IHTMLInputElement *iface, BSTR v) { HTMLInputElement *This = HTMLINPUT_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString type_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + /* + * FIXME: + * On IE setting type works only on dynamically created elements before adding them to DOM tree. + */ + nsAString_InitDepend(&type_str, v); + nsres = nsIDOMHTMLInputElement_SetType(This->nsinput, &type_str); + nsAString_Finish(&type_str); + if(NS_FAILED(nsres)) { + ERR("SetType failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLInputElement_get_type(IHTMLInputElement *iface, BSTR *p) @@ -180,8 +196,20 @@ static HRESULT WINAPI HTMLInputElement_get_value(IHTMLInputElement *iface, BSTR static HRESULT WINAPI HTMLInputElement_put_name(IHTMLInputElement *iface, BSTR v) { HTMLInputElement *This = HTMLINPUT_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString name_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&name_str, v); + nsres = nsIDOMHTMLInputElement_SetName(This->nsinput, &name_str); + nsAString_Finish(&name_str); + if(NS_FAILED(nsres)) { + ERR("SetName failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLInputElement_get_name(IHTMLInputElement *iface, BSTR *p) @@ -190,6 +218,7 @@ static HRESULT WINAPI HTMLInputElement_get_name(IHTMLInputElement *iface, BSTR * nsAString name_str; const PRUnichar *name; nsresult nsres; + HRESULT hres = S_OK; TRACE("(%p)->(%p)\n", This, p); @@ -198,16 +227,14 @@ static HRESULT WINAPI HTMLInputElement_get_name(IHTMLInputElement *iface, BSTR * nsres = nsIDOMHTMLInputElement_GetName(This->nsinput, &name_str); if(NS_SUCCEEDED(nsres)) { nsAString_GetData(&name_str, &name); - *p = SysAllocString(name); + *p = *name ? SysAllocString(name) : NULL; }else { ERR("GetName failed: %08x\n", nsres); - return E_FAIL; + hres = E_FAIL; } nsAString_Finish(&name_str); - - TRACE("name=%s\n", debugstr_w(*p)); - return S_OK; + return hres; } static HRESULT WINAPI HTMLInputElement_put_status(IHTMLInputElement *iface, VARIANT_BOOL v) diff --git a/dll/win32/mshtml/htmloption.c b/dll/win32/mshtml/htmloption.c index 3e037627bf1..b8166341bd4 100644 --- a/dll/win32/mshtml/htmloption.c +++ b/dll/win32/mshtml/htmloption.c @@ -98,15 +98,35 @@ static HRESULT WINAPI HTMLOptionElement_Invoke(IHTMLOptionElement *iface, DISPID static HRESULT WINAPI HTMLOptionElement_put_selected(IHTMLOptionElement *iface, VARIANT_BOOL v) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%x)\n", This, v); + + nsres = nsIDOMHTMLOptionElement_SetSelected(This->nsoption, v != VARIANT_FALSE); + if(NS_FAILED(nsres)) { + ERR("SetSelected failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLOptionElement_get_selected(IHTMLOptionElement *iface, VARIANT_BOOL *p) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRBool selected; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLOptionElement_GetSelected(This->nsoption, &selected); + if(NS_FAILED(nsres)) { + ERR("GetSelected failed: %08x\n", nsres); + return E_FAIL; + } + + *p = selected ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } static HRESULT WINAPI HTMLOptionElement_put_value(IHTMLOptionElement *iface, BSTR v) diff --git a/dll/win32/mshtml/htmlselect.c b/dll/win32/mshtml/htmlselect.c index 6698606a4c4..f3aa36f650f 100644 --- a/dll/win32/mshtml/htmlselect.c +++ b/dll/win32/mshtml/htmlselect.c @@ -42,6 +42,43 @@ typedef struct { #define HTMLSELECT(x) ((IHTMLSelectElement*) &(x)->lpHTMLSelectElementVtbl) +static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret) +{ + nsIDOMHTMLOptionsCollection *nscol; + nsIDOMNode *nsnode; + nsresult nsres; + + nsres = nsIDOMHTMLSelectElement_GetOptions(This->nsselect, &nscol); + if(NS_FAILED(nsres)) { + ERR("GetOptions failed: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMHTMLOptionsCollection_Item(nscol, i, &nsnode); + nsIDOMHTMLOptionsCollection_Release(nscol); + if(NS_FAILED(nsres)) { + ERR("Item failed: %08x\n", nsres); + return E_FAIL; + } + + if(nsnode) { + HTMLDOMNode *node; + + node = get_node(This->element.node.doc, nsnode, TRUE); + nsIDOMNode_Release(nsnode); + if(!node) { + ERR("Could not find node\n"); + return E_FAIL; + } + + IHTMLDOMNode_AddRef(HTMLDOMNODE(node)); + *ret = (IDispatch*)HTMLDOMNODE(node); + }else { + *ret = NULL; + } + return S_OK; +} + #define HTMLSELECT_THIS(iface) DEFINE_THIS(HTMLSelectElement, HTMLSelectElement, iface) static HRESULT WINAPI HTMLSelectElement_QueryInterface(IHTMLSelectElement *iface, @@ -170,8 +207,12 @@ static HRESULT WINAPI HTMLSelectElement_get_name(IHTMLSelectElement *iface, BSTR static HRESULT WINAPI HTMLSelectElement_get_options(IHTMLSelectElement *iface, IDispatch **p) { HTMLSelectElement *This = HTMLSELECT_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + *p = (IDispatch*)HTMLSELECT(This); + IDispatch_AddRef(*p); + return S_OK; } static HRESULT WINAPI HTMLSelectElement_put_onchange(IHTMLSelectElement *iface, VARIANT v) @@ -364,8 +405,15 @@ static HRESULT WINAPI HTMLSelectElement_remove(IHTMLSelectElement *iface, LONG i static HRESULT WINAPI HTMLSelectElement_put_length(IHTMLSelectElement *iface, LONG v) { HTMLSelectElement *This = HTMLSELECT_THIS(iface); - FIXME("(%p)->(%d)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%d)\n", This, v); + + nsres = nsIDOMHTMLSelectElement_SetLength(This->nsselect, v); + if(NS_FAILED(nsres)) + ERR("SetLength failed: %08x\n", nsres); + + return S_OK; } static HRESULT WINAPI HTMLSelectElement_get_length(IHTMLSelectElement *iface, LONG *p) @@ -397,7 +445,20 @@ static HRESULT WINAPI HTMLSelectElement_item(IHTMLSelectElement *iface, VARIANT VARIANT index, IDispatch **pdisp) { HTMLSelectElement *This = HTMLSELECT_THIS(iface); - FIXME("(%p)->(v v %p)\n", This, pdisp); + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); + + if(!pdisp) + return E_POINTER; + *pdisp = NULL; + + if(V_VT(&name) == VT_I4) { + if(V_I4(&name) < 0) + return E_INVALIDARG; + return htmlselect_item(This, V_I4(&name), pdisp); + } + + FIXME("Unsupported args\n"); return E_NOTIMPL; } @@ -493,6 +554,60 @@ static HRESULT HTMLSelectElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BO return IHTMLSelectElement_get_disabled(HTMLSELECT(This), p); } +#define DISPID_OPTIONCOL_0 MSHTML_DISPID_CUSTOM_MIN + +static HRESULT HTMLSelectElement_get_dispid(HTMLDOMNode *iface, BSTR name, DWORD flags, DISPID *dispid) +{ + const WCHAR *ptr; + DWORD idx = 0; + + for(ptr = name; *ptr && isdigitW(*ptr); ptr++) { + idx = idx*10 + (*ptr-'0'); + if(idx > MSHTML_CUSTOM_DISPID_CNT) { + WARN("too big idx\n"); + return DISP_E_UNKNOWNNAME; + } + } + if(*ptr) + return DISP_E_UNKNOWNNAME; + + *dispid = DISPID_OPTIONCOL_0 + idx; + return S_OK; +} + +static HRESULT HTMLSelectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + HTMLSelectElement *This = HTMLSELECT_NODE_THIS(iface); + + TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); + + switch(flags) { + case DISPATCH_PROPERTYGET: { + IDispatch *ret; + HRESULT hres; + + hres = htmlselect_item(This, id-DISPID_OPTIONCOL_0, &ret); + if(FAILED(hres)) + return hres; + + if(ret) { + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = ret; + }else { + V_VT(res) = VT_NULL; + } + break; + } + + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; +} + #undef HTMLSELECT_NODE_THIS static const NodeImplVtbl HTMLSelectElementImplVtbl = { @@ -501,7 +616,11 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = { NULL, NULL, HTMLSelectElementImpl_put_disabled, - HTMLSelectElementImpl_get_disabled + HTMLSelectElementImpl_get_disabled, + NULL, + NULL, + HTMLSelectElement_get_dispid, + HTMLSelectElement_invoke }; static const tid_t HTMLSelectElement_tids[] = { diff --git a/dll/win32/mshtml/htmltextarea.c b/dll/win32/mshtml/htmltextarea.c index 9ded8ac6e12..dd33c72df21 100644 --- a/dll/win32/mshtml/htmltextarea.c +++ b/dll/win32/mshtml/htmltextarea.c @@ -105,8 +105,20 @@ static HRESULT WINAPI HTMLTextAreaElement_get_type(IHTMLTextAreaElement *iface, static HRESULT WINAPI HTMLTextAreaElement_put_value(IHTMLTextAreaElement *iface, BSTR v) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString value_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&value_str, v); + nsres = nsIDOMHTMLTextAreaElement_SetValue(This->nstextarea, &value_str); + nsAString_Finish(&value_str); + if(NS_FAILED(nsres)) { + ERR("SetValue failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, BSTR *p) @@ -115,6 +127,7 @@ static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, nsAString value_str; const PRUnichar *value; nsresult nsres; + HRESULT hres = S_OK; TRACE("(%p)->(%p)\n", This, p); @@ -123,15 +136,14 @@ static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, nsres = nsIDOMHTMLTextAreaElement_GetValue(This->nstextarea, &value_str); if(NS_SUCCEEDED(nsres)) { nsAString_GetData(&value_str, &value); - *p = SysAllocString(value); + *p = *value ? SysAllocString(value) : NULL; }else { ERR("GetValue failed: %08x\n", nsres); + hres = E_FAIL; } nsAString_Finish(&value_str); - - TRACE("%s\n", debugstr_w(*p)); - return S_OK; + return hres; } static HRESULT WINAPI HTMLTextAreaElement_put_name(IHTMLTextAreaElement *iface, BSTR v) @@ -253,15 +265,35 @@ static HRESULT WINAPI HTMLTextAreaElement_get_onselect(IHTMLTextAreaElement *ifa static HRESULT WINAPI HTMLTextAreaElement_put_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL v) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%x)\n", This, v); + + nsres = nsIDOMHTMLTextAreaElement_SetReadOnly(This->nstextarea, v != VARIANT_FALSE); + if(NS_FAILED(nsres)) { + ERR("SetReadOnly failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTextAreaElement_get_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL *p) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + PRBool b; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLTextAreaElement_GetReadOnly(This->nstextarea, &b); + if(NS_FAILED(nsres)) { + ERR("GetReadOnly failed: %08x\n", nsres); + return E_FAIL; + } + + *p = b ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } static HRESULT WINAPI HTMLTextAreaElement_put_rows(IHTMLTextAreaElement *iface, LONG v) diff --git a/dll/win32/mshtml/htmlwindow.c b/dll/win32/mshtml/htmlwindow.c index 5dbea55905c..1701b533288 100644 --- a/dll/win32/mshtml/htmlwindow.c +++ b/dll/win32/mshtml/htmlwindow.c @@ -511,20 +511,34 @@ static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID return clear_task_timer(&This->doc->basedoc, FALSE, timerID); } +#define MAX_MESSAGE_LEN 2000 + static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - WCHAR wszTitle[100]; + WCHAR title[100], *msg = message; + DWORD len; TRACE("(%p)->(%s)\n", This, debugstr_w(message)); - if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle, - sizeof(wszTitle)/sizeof(WCHAR))) { + if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, title, + sizeof(title)/sizeof(WCHAR))) { WARN("Could not load message box title: %d\n", GetLastError()); return S_OK; } - MessageBoxW(This->doc_obj->hwnd, message, wszTitle, MB_ICONWARNING); + len = SysStringLen(message); + if(len > MAX_MESSAGE_LEN) { + msg = heap_alloc((MAX_MESSAGE_LEN+1)*sizeof(WCHAR)); + if(!msg) + return E_OUTOFMEMORY; + memcpy(msg, message, MAX_MESSAGE_LEN*sizeof(WCHAR)); + msg[MAX_MESSAGE_LEN] = 0; + } + + MessageBoxW(This->doc_obj->hwnd, msg, title, MB_ICONWARNING); + if(msg != message) + heap_free(msg); return S_OK; } diff --git a/dll/win32/mshtml/install.c b/dll/win32/mshtml/install.c index 4122194a7cc..e47c28423d0 100644 --- a/dll/win32/mshtml/install.c +++ b/dll/win32/mshtml/install.c @@ -60,6 +60,11 @@ static const WCHAR mshtml_keyW[] = '\\','W','i','n','e', '\\','M','S','H','T','M','L',0}; +static const CHAR mshtml_keyA[] = + {'S','o','f','t','w','a','r','e', + '\\','W','i','n','e', + '\\','M','S','H','T','M','L',0}; + static HWND install_dialog = NULL; static LPWSTR tmp_file_name = NULL; static HANDLE tmp_file = INVALID_HANDLE_VALUE; @@ -225,23 +230,18 @@ static BOOL install_from_unix_file(const char *file_name) static BOOL install_from_registered_dir(void) { char *file_name; - HKEY hkey; DWORD res, type, size = MAX_PATH; BOOL ret; - /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ - res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey); - if(res != ERROR_SUCCESS) - return FALSE; - file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); - res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); + /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ + res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); if(res == ERROR_MORE_DATA) { file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME)); - res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); + res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); } - RegCloseKey(hkey); - if(res != ERROR_SUCCESS || type != REG_SZ) { + + if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) { heap_free(file_name); return FALSE; } diff --git a/dll/win32/mshtml/mshtml_private.h b/dll/win32/mshtml/mshtml_private.h index 3db8d791e48..4deb4d6357d 100644 --- a/dll/win32/mshtml/mshtml_private.h +++ b/dll/win32/mshtml/mshtml_private.h @@ -144,6 +144,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_DISPID_CUSTOM_MIN 0x60000000 #define MSHTML_DISPID_CUSTOM_MAX 0x6fffffff +#define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN) typedef struct { HRESULT (*value)(IUnknown*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); @@ -727,8 +728,10 @@ HRESULT call_set_active_object(IOleInPlaceUIWindow*,IOleInPlaceActiveObject*); void *nsalloc(size_t) __WINE_ALLOC_SIZE(1); void nsfree(void*); +void nsACString_InitDepend(nsACString*,const char*); void nsACString_SetData(nsACString*,const char*); PRUint32 nsACString_GetData(const nsACString*,const char**); +void nsACString_Finish(nsACString*); BOOL nsAString_Init(nsAString*,const PRUnichar*); void nsAString_InitDepend(nsAString*,const PRUnichar*); diff --git a/dll/win32/mshtml/nsembed.c b/dll/win32/mshtml/nsembed.c index 8a590079278..56c5d945618 100644 --- a/dll/win32/mshtml/nsembed.c +++ b/dll/win32/mshtml/nsembed.c @@ -32,6 +32,7 @@ #include "wine/unicode.h" #include "mshtml_private.h" +#include "htmlevent.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); WINE_DECLARE_DEBUG_CHANNEL(gecko); @@ -48,20 +49,14 @@ WINE_DECLARE_DEBUG_CHANNEL(gecko); #define PR_UINT32_MAX 0xffffffff -struct nsCStringContainer { - void *v; - void *d1; - PRUint32 d2; - PRUint32 d3; -}; - #define NS_STRING_CONTAINER_INIT_DEPEND 0x0002 +#define NS_CSTRING_CONTAINER_INIT_DEPEND 0x0002 static nsresult (*NS_InitXPCOM2)(nsIServiceManager**,void*,void*); static nsresult (*NS_ShutdownXPCOM)(nsIServiceManager*); static nsresult (*NS_GetComponentRegistrar)(nsIComponentRegistrar**); static nsresult (*NS_StringContainerInit2)(nsStringContainer*,const PRUnichar*,PRUint32,PRUint32); -static nsresult (*NS_CStringContainerInit)(nsCStringContainer*); +static nsresult (*NS_CStringContainerInit2)(nsCStringContainer*,const char*,PRUint32,PRUint32); static nsresult (*NS_StringContainerFinish)(nsStringContainer*); static nsresult (*NS_CStringContainerFinish)(nsCStringContainer*); static nsresult (*NS_StringSetData)(nsAString*,const PRUnichar*,PRUint32); @@ -188,7 +183,7 @@ static BOOL load_xpcom(const PRUnichar *gre_path) NS_DLSYM(NS_ShutdownXPCOM); NS_DLSYM(NS_GetComponentRegistrar); NS_DLSYM(NS_StringContainerInit2); - NS_DLSYM(NS_CStringContainerInit); + NS_DLSYM(NS_CStringContainerInit2); NS_DLSYM(NS_StringContainerFinish); NS_DLSYM(NS_CStringContainerFinish); NS_DLSYM(NS_StringSetData); @@ -526,11 +521,18 @@ void nsfree(void *mem) nsIMemory_Free(nsmem, mem); } -static void nsACString_Init(nsACString *str, const char *data) +static BOOL nsACString_Init(nsACString *str, const char *data) { - NS_CStringContainerInit(str); - if(data) - nsACString_SetData(str, data); + return NS_SUCCEEDED(NS_CStringContainerInit2(str, data, PR_UINT32_MAX, 0)); +} + +/* + * Initializes nsACString with data owned by caller. + * Caller must ensure that data is valid during lifetime of string object. + */ +void nsACString_InitDepend(nsACString *str, const char *data) +{ + NS_CStringContainerInit2(str, data, PR_UINT32_MAX, NS_CSTRING_CONTAINER_INIT_DEPEND); } void nsACString_SetData(nsACString *str, const char *data) @@ -543,7 +545,7 @@ PRUint32 nsACString_GetData(const nsACString *str, const char **data) return NS_CStringGetData(str, data, NULL); } -static void nsACString_Finish(nsACString *str) +void nsACString_Finish(nsACString *str) { NS_CStringContainerFinish(str); } @@ -1006,6 +1008,8 @@ static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuList TRACE("(%p)->(%08x %p %p)\n", This, aContextFlags, aEvent, aNode); + fire_event(This->doc->basedoc.doc_node /* FIXME */, EVENTID_CONTEXTMENU, TRUE, aNode, aEvent); + nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMMouseEvent interface: %08x\n", nsres); diff --git a/dll/win32/mshtml/nsiface.idl b/dll/win32/mshtml/nsiface.idl index 66ab8e6a49b..4ccc64a7c02 100644 --- a/dll/win32/mshtml/nsiface.idl +++ b/dll/win32/mshtml/nsiface.idl @@ -119,7 +119,6 @@ typedef nsISupports nsIDOMDOMImplementation; typedef nsISupports nsIDOMCDATASection; typedef nsISupports nsIDOMProcessingInstruction; typedef nsISupports nsIDOMEntityReference; -typedef nsISupports nsIDOMHTMLOptionsCollection; typedef nsISupports nsIWebProgressListener; typedef nsISupports nsIDOMCSSValue; typedef nsISupports nsIPrintSession; @@ -1319,6 +1318,20 @@ interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement nsresult SetValue(const nsAString *aValue); } +[ + object, + uuid(bce0213c-f70f-488f-b93f-688acca55d63), + local + /* FROZEN */ +] +interface nsIDOMHTMLOptionsCollection : nsISupports +{ + nsresult GetLength(PRUint32 *aLength); + nsresult SetLength(PRUint32 aLength); + nsresult Item(PRUint32 index, nsIDOMNode **_retval); + nsresult NamedItem(const nsAString *name, nsIDOMNode **_retval); +} + [ object, uuid(a6cf9090-15b3-11d2-932e-00805f8add32), diff --git a/dll/win32/mshtml/nsio.c b/dll/win32/mshtml/nsio.c index 0c8e45704d7..63c9a6a3d6a 100644 --- a/dll/win32/mshtml/nsio.c +++ b/dll/win32/mshtml/nsio.c @@ -196,16 +196,15 @@ static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri) url = heap_strdupW(uri->wine_url); hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url); - heap_free(url); - if(hres != S_OK || !new_url) - return FALSE; - - if(strcmpW(url, new_url)) { - FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url)); - ret = TRUE; + if(hres == S_OK && new_url) { + if(strcmpW(url, new_url)) { + FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url)); + ret = TRUE; + } + CoTaskMemFree(new_url); } - CoTaskMemFree(new_url); + heap_free(url); return ret; } @@ -229,7 +228,7 @@ nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, PRBool *_retva } wine_uri->is_doc_uri = TRUE; - *_retval = translate_url(nscontainer->doc->basedoc.doc_obj, wine_uri); + *_retval = translate_url(nscontainer->doc, wine_uri); } nsIURI_Release(NSURI(wine_uri)); @@ -2453,6 +2452,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * HTMLWindow *window = NULL; nsIURI *uri = NULL; LPCWSTR base_wine_url = NULL; + nsACString spec_str; nsresult nsres; nsACString_GetData(aSpec, &spec); @@ -2485,7 +2485,9 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * } } + nsACString_InitDepend(&spec_str, spec); nsres = nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, &uri); + nsACString_Finish(&spec_str); if(NS_FAILED(nsres)) TRACE("NewURI failed: %08x\n", nsres); diff --git a/dll/win32/mshtml/ros_diff.patch b/dll/win32/mshtml/ros_diff.patch new file mode 100644 index 00000000000..51add30a06c --- /dev/null +++ b/dll/win32/mshtml/ros_diff.patch @@ -0,0 +1,43 @@ +--- C:/Users/CHRIST~1/AppData/Local/Temp/install.-rev47414.svn001.tmp.c Sa Mai 29 16:46:40 2010 ++++ C:/Users/Christoph/Desktop/Projekte/ReactOS/dll/win32/mshtml/install.c Sa Mai 29 16:43:49 2010 +@@ -60,6 +60,11 @@ + '\\','W','i','n','e', + '\\','M','S','H','T','M','L',0}; + ++static const CHAR mshtml_keyA[] = ++ {'S','o','f','t','w','a','r','e', ++ '\\','W','i','n','e', ++ '\\','M','S','H','T','M','L',0}; ++ + static HWND install_dialog = NULL; + static LPWSTR tmp_file_name = NULL; + static HANDLE tmp_file = INVALID_HANDLE_VALUE; +@@ -225,23 +230,18 @@ + static BOOL install_from_registered_dir(void) + { + char *file_name; +- HKEY hkey; + DWORD res, type, size = MAX_PATH; + BOOL ret; + ++ file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); + /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ +- res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey); +- if(res != ERROR_SUCCESS) +- return FALSE; +- +- file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); +- res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); ++ res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); + if(res == ERROR_MORE_DATA) { + file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME)); +- res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); ++ res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); + } +- RegCloseKey(hkey); +- if(res != ERROR_SUCCESS || type != REG_SZ) { ++ ++ if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) { + heap_free(file_name); + return FALSE; + } diff --git a/dll/win32/mshtml/secmgr.c b/dll/win32/mshtml/secmgr.c index e35a83b5c29..c74e19fd93b 100644 --- a/dll/win32/mshtml/secmgr.c +++ b/dll/win32/mshtml/secmgr.c @@ -90,6 +90,8 @@ static HRESULT confirm_safety(HTMLDocumentNode *This, const WCHAR *url, struct C IObjectSafety *obj_safety; HRESULT hres; + TRACE("%s %p %s\n", debugstr_w(url), cs->pUnk, debugstr_guid(&cs->clsid)); + /* FIXME: Check URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY */ hres = IInternetSecurityManager_ProcessUrlAction(This->secmgr, url, URLACTION_SCRIPT_SAFE_ACTIVEX, @@ -119,11 +121,17 @@ static HRESULT confirm_safety(HTMLDocumentNode *This, const WCHAR *url, struct C } hres = IObjectSafety_GetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, &supported_opts, &enabled_opts); - if(SUCCEEDED(hres)) { - enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER; - if(supported_opts & INTERFACE_USES_SECURITY_MANAGER) - enabled_opts |= INTERFACE_USES_SECURITY_MANAGER; - hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts); + if(FAILED(hres)) + supported_opts = 0; + + enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER; + if(supported_opts & INTERFACE_USES_SECURITY_MANAGER) + enabled_opts |= INTERFACE_USES_SECURITY_MANAGER; + + hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts); + if(FAILED(hres)) { + enabled_opts &= ~INTERFACE_USES_SECURITY_MANAGER; + hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatch, enabled_opts, enabled_opts); } IObjectSafety_Release(obj_safety); @@ -175,6 +183,7 @@ static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHos *(DWORD*)*ppPolicy = policy; *pcbPolicy = sizeof(policy); + TRACE("policy %x\n", policy); return S_OK; } diff --git a/dll/win32/mshtml/task.c b/dll/win32/mshtml/task.c index eae51cacd15..c896179715b 100644 --- a/dll/win32/mshtml/task.c +++ b/dll/win32/mshtml/task.c @@ -222,7 +222,6 @@ static void call_timer_disp(IDispatch *disp) static LRESULT process_timer(void) { thread_data_t *thread_data = get_thread_data(TRUE); - HTMLDocument *doc; IDispatch *disp; DWORD tc; task_timer_t *timer; @@ -238,7 +237,6 @@ static LRESULT process_timer(void) return 0; } - doc = timer->doc; disp = timer->disp; IDispatch_AddRef(disp); diff --git a/dll/win32/msi/action.c b/dll/win32/msi/action.c index 81dcba43ae9..4c5597279ab 100644 --- a/dll/win32/msi/action.c +++ b/dll/win32/msi/action.c @@ -96,8 +96,6 @@ static const WCHAR szAllocateRegistrySpace[] = {'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y','S','p','a','c','e',0}; static const WCHAR szBindImage[] = {'B','i','n','d','I','m','a','g','e',0}; -static const WCHAR szCCPSearch[] = - {'C','C','P','S','e','a','r','c','h',0}; static const WCHAR szDeleteServices[] = {'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0}; static const WCHAR szDisableRollback[] = @@ -126,8 +124,6 @@ static const WCHAR szPublishComponents[] = {'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0}; static const WCHAR szRegisterComPlus[] = {'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0}; -static const WCHAR szRegisterFonts[] = - {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; static const WCHAR szRegisterUser[] = {'R','e','g','i','s','t','e','r','U','s','e','r',0}; static const WCHAR szRemoveEnvironmentStrings[] = @@ -160,18 +156,8 @@ static const WCHAR szUnpublishComponents[] = {'U','n','p','u','b','l','i','s','h', 'C','o','m','p','o','n','e','n','t','s',0}; static const WCHAR szUnpublishFeatures[] = {'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0}; -static const WCHAR szUnregisterClassInfo[] = - {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0}; static const WCHAR szUnregisterComPlus[] = {'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0}; -static const WCHAR szUnregisterExtensionInfo[] = - {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0}; -static const WCHAR szUnregisterFonts[] = - {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0}; -static const WCHAR szUnregisterMIMEInfo[] = - {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0}; -static const WCHAR szUnregisterProgIdInfo[] = - {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0}; static const WCHAR szUnregisterTypeLibraries[] = {'U','n','r','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0}; static const WCHAR szValidateProductID[] = @@ -291,9 +277,13 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, if (lstrlenW(prop) > 0) { + UINT r = msi_set_property( package->db, prop, val ); + TRACE("Found commandline property (%s) = (%s)\n", debugstr_w(prop), debugstr_w(val)); - MSI_SetPropertyW(package,prop,val); + + if (r == ERROR_SUCCESS && !strcmpW( prop, cszSourceDir )) + msi_reset_folders( package, TRUE ); } msi_free(val); msi_free(prop); @@ -347,7 +337,7 @@ static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch LPWSTR prod_code, patch_product, langid = NULL, template = NULL; UINT ret = ERROR_FUNCTION_FAILED; - prod_code = msi_dup_property( package, szProductCode ); + prod_code = msi_dup_property( package->db, szProductCode ); patch_product = msi_get_suminfo_product( patch ); TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product)); @@ -379,7 +369,7 @@ static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch goto end; } - langid = msi_dup_property( package, szSystemLanguageID ); + langid = msi_dup_property( package->db, szSystemLanguageID ); if (!langid) { msiobj_release( &si->hdr ); @@ -443,7 +433,7 @@ UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ) LPWSTR guid_list, *guids, product_code; UINT i, ret = ERROR_FUNCTION_FAILED; - product_code = msi_dup_property( package, szProductCode ); + product_code = msi_dup_property( package->db, szProductCode ); if (!product_code) { /* FIXME: the property ProductCode should be written into the DB somewhere */ @@ -490,8 +480,8 @@ static UINT msi_set_media_source_prop(MSIPACKAGE *package) if (MSI_ViewFetch(view, &rec) == ERROR_SUCCESS) { prop = MSI_RecordGetString(rec, 1); - patch = msi_dup_property(package, szPatch); - MSI_SetPropertyW(package, prop, patch); + patch = msi_dup_property(package->db, szPatch); + msi_set_property(package->db, prop, patch); msi_free(patch); } @@ -502,76 +492,130 @@ done: return r; } -static UINT msi_parse_patch_summary( MSIPACKAGE *package, MSIDATABASE *patch_db ) +UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ) { - MSISUMMARYINFO *si; - LPWSTR str, *substorage; - UINT i, r = ERROR_SUCCESS; + MSIPATCHINFO *pi; + UINT r = ERROR_SUCCESS; - si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); - if (!si) - return ERROR_FUNCTION_FAILED; + pi = msi_alloc_zero( sizeof(MSIPATCHINFO) ); + if (!pi) + return ERROR_OUTOFMEMORY; - if (msi_check_patch_applicable( package, si ) != ERROR_SUCCESS) + pi->patchcode = msi_suminfo_dup_string( si, PID_REVNUMBER ); + if (!pi->patchcode) { - TRACE("Patch not applicable\n"); - return ERROR_SUCCESS; + msi_free( pi ); + return ERROR_OUTOFMEMORY; } - package->patch = msi_alloc(sizeof(MSIPATCHINFO)); - if (!package->patch) + pi->transforms = msi_suminfo_dup_string( si, PID_LASTAUTHOR ); + if (!pi->transforms) + { + msi_free( pi->patchcode ); + msi_free( pi ); return ERROR_OUTOFMEMORY; + } - package->patch->patchcode = msi_suminfo_dup_string(si, PID_REVNUMBER); - if (!package->patch->patchcode) - return ERROR_OUTOFMEMORY; + *patch = pi; + return r; +} - /* enumerate the substorage */ - str = msi_suminfo_dup_string( si, PID_LASTAUTHOR ); - package->patch->transforms = str; +UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch ) +{ + UINT i, r = ERROR_SUCCESS; + WCHAR **substorage; - substorage = msi_split_string( str, ';' ); - for ( i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++ ) + /* apply substorage transforms */ + substorage = msi_split_string( patch->transforms, ';' ); + for (i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++) r = msi_apply_substorage_transform( package, patch_db, substorage[i] ); msi_free( substorage ); - msiobj_release( &si->hdr ); + if (r != ERROR_SUCCESS) + return r; - msi_set_media_source_prop(package); + msi_set_media_source_prop( package ); - return r; + /* + * There might be a CAB file in the patch package, + * so append it to the list of storages to search for streams. + */ + append_storage_to_db( package->db, patch_db->storage ); + + list_add_tail( &package->patches, &patch->entry ); + return ERROR_SUCCESS; } static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file ) { + static const WCHAR dotmsp[] = {'.','m','s','p',0}; MSIDATABASE *patch_db = NULL; - UINT r; + WCHAR localfile[MAX_PATH]; + MSISUMMARYINFO *si; + MSIPATCHINFO *patch = NULL; + UINT r = ERROR_SUCCESS; TRACE("%p %s\n", package, debugstr_w( file ) ); - /* FIXME: - * We probably want to make sure we only open a patch collection here. - * Patch collections (.msp) and databases (.msi) have different GUIDs - * but currently MSI_OpenDatabaseW will accept both. - */ - r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &patch_db ); + r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db ); if ( r != ERROR_SUCCESS ) { ERR("failed to open patch collection %s\n", debugstr_w( file ) ); return r; } - msi_parse_patch_summary( package, patch_db ); + si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); + if (!si) + { + msiobj_release( &patch_db->hdr ); + return ERROR_FUNCTION_FAILED; + } - /* - * There might be a CAB file in the patch package, - * so append it to the list of storage to search for streams. - */ - append_storage_to_db( package->db, patch_db->storage ); + r = msi_check_patch_applicable( package, si ); + if (r != ERROR_SUCCESS) + { + TRACE("patch not applicable\n"); + r = ERROR_SUCCESS; + goto done; + } + r = msi_parse_patch_summary( si, &patch ); + if ( r != ERROR_SUCCESS ) + goto done; + + r = msi_get_local_package_name( localfile, dotmsp ); + if ( r != ERROR_SUCCESS ) + goto done; + + TRACE("copying to local package %s\n", debugstr_w(localfile)); + + if (!CopyFileW( file, localfile, FALSE )) + { + ERR("Unable to copy package (%s -> %s) (error %u)\n", + debugstr_w(file), debugstr_w(localfile), GetLastError()); + r = GetLastError(); + goto done; + } + patch->localfile = strdupW( localfile ); + + r = msi_apply_patch_db( package, patch_db, patch ); + if ( r != ERROR_SUCCESS ) + WARN("patch failed to apply %u\n", r); + +done: + msiobj_release( &si->hdr ); msiobj_release( &patch_db->hdr ); + if (patch && r != ERROR_SUCCESS) + { + if (patch->localfile) + DeleteFileW( patch->localfile ); - return ERROR_SUCCESS; + msi_free( patch->patchcode ); + msi_free( patch->transforms ); + msi_free( patch->localfile ); + msi_free( patch ); + } + return r; } /* get the PATCH property, and apply all the patches it specifies */ @@ -580,7 +624,7 @@ static UINT msi_apply_patches( MSIPACKAGE *package ) LPWSTR patch_list, *patches; UINT i, r = ERROR_SUCCESS; - patch_list = msi_dup_property( package, szPatch ); + patch_list = msi_dup_property( package->db, szPatch ); TRACE("patches to be applied: %s\n", debugstr_w( patch_list ) ); @@ -601,7 +645,7 @@ static UINT msi_apply_transforms( MSIPACKAGE *package ) LPWSTR xform_list, *xforms; UINT i, r = ERROR_SUCCESS; - xform_list = msi_dup_property( package, szTransforms ); + xform_list = msi_dup_property( package->db, szTransforms ); xforms = msi_split_string( xform_list, ';' ); for( i=0; xforms && xforms[i] && r == ERROR_SUCCESS; i++ ) @@ -644,71 +688,76 @@ static BOOL ui_sequence_exists( MSIPACKAGE *package ) static UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) { - LPWSTR p, db; LPWSTR source, check; - DWORD len; - static const WCHAR szOriginalDatabase[] = - {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; - - db = msi_dup_property( package, szOriginalDatabase ); - if (!db) - return ERROR_OUTOFMEMORY; - - p = strrchrW( db, '\\' ); - if (!p) + if (msi_get_property_int( package->db, szInstalled, 0 )) { - p = strrchrW( db, '/' ); + HKEY hkey; + + MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE ); + source = msi_reg_get_val_str( hkey, INSTALLPROPERTY_INSTALLSOURCEW ); + RegCloseKey( hkey ); + } + else + { + LPWSTR p, db; + DWORD len; + + db = msi_dup_property( package->db, szOriginalDatabase ); + if (!db) + return ERROR_OUTOFMEMORY; + + p = strrchrW( db, '\\' ); if (!p) { - msi_free(db); - return ERROR_SUCCESS; + p = strrchrW( db, '/' ); + if (!p) + { + msi_free(db); + return ERROR_SUCCESS; + } } + + len = p - db + 2; + source = msi_alloc( len * sizeof(WCHAR) ); + lstrcpynW( source, db, len ); + msi_free( db ); } - len = p - db + 2; - source = msi_alloc( len * sizeof(WCHAR) ); - lstrcpynW( source, db, len ); - - check = msi_dup_property( package, cszSourceDir ); + check = msi_dup_property( package->db, cszSourceDir ); if (!check || replace) - MSI_SetPropertyW( package, cszSourceDir, source ); - + { + UINT r = msi_set_property( package->db, cszSourceDir, source ); + if (r == ERROR_SUCCESS) + msi_reset_folders( package, TRUE ); + } msi_free( check ); - check = msi_dup_property( package, cszSOURCEDIR ); + check = msi_dup_property( package->db, cszSOURCEDIR ); if (!check || replace) - MSI_SetPropertyW( package, cszSOURCEDIR, source ); + msi_set_property( package->db, cszSOURCEDIR, source ); msi_free( check ); msi_free( source ); - msi_free( db ); return ERROR_SUCCESS; } static BOOL needs_ui_sequence(MSIPACKAGE *package) { - INT level = msi_get_property_int(package, szUILevel, 0); + INT level = msi_get_property_int(package->db, szUILevel, 0); return (level & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED; } -static UINT msi_set_context(MSIPACKAGE *package) +UINT msi_set_context(MSIPACKAGE *package) { - WCHAR val[10]; - DWORD sz = 10; - DWORD num; - UINT r; + int num; package->Context = MSIINSTALLCONTEXT_USERUNMANAGED; - r = MSI_GetPropertyW(package, szAllUsers, val, &sz); - if (r == ERROR_SUCCESS) - { - num = atolW(val); - if (num == 1 || num == 2) - package->Context = MSIINSTALLCONTEXT_MACHINE; - } + num = msi_get_property_int(package->db, szAllUsers, 0); + if (num == 1 || num == 2) + package->Context = MSIINSTALLCONTEXT_MACHINE; return ERROR_SUCCESS; } @@ -1325,6 +1374,26 @@ done: return r; } +static UINT load_file_disk_id( MSIPACKAGE *package, MSIFILE *file ) +{ + MSIRECORD *row; + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','`','D','i','s','k','I','d','`',' ', 'F','R','O','M',' ', + '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', + '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',' ','%','i',0}; + + row = MSI_QueryGetRecord( package->db, query, file->Sequence ); + if (!row) + { + WARN("query failed\n"); + return ERROR_FUNCTION_FAILED; + } + + file->disk_id = MSI_RecordGetInteger( row, 1 ); + msiobj_release( &row->hdr ); + return ERROR_SUCCESS; +} + static UINT load_file(MSIRECORD *row, LPVOID param) { MSIPACKAGE* package = param; @@ -1386,6 +1455,7 @@ static UINT load_file(MSIRECORD *row, LPVOID param) } load_file_hash(package, file); + load_file_disk_id(package, file); TRACE("File Loaded (%s)\n",debugstr_w(file->File)); @@ -1470,7 +1540,7 @@ static UINT load_folder( MSIRECORD *row, LPVOID param ) folder->Parent = msi_dup_record_field( row, 2 ); - folder->Property = msi_dup_property( package, folder->Directory ); + folder->Property = msi_dup_property( package->db, folder->Directory ); list_add_tail( &package->folders, &folder->entry ); @@ -1517,8 +1587,8 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package) static const WCHAR szCosting[] = {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 }; - MSI_SetPropertyW(package, szCosting, szZero); - MSI_SetPropertyW(package, cszRootDrive, c_colon); + msi_set_property( package->db, szCosting, szZero ); + msi_set_property( package->db, cszRootDrive, c_colon ); load_all_folders( package ); load_all_components( package ); @@ -1611,7 +1681,7 @@ static BOOL process_state_property(MSIPACKAGE* package, int level, LPWSTR override; MSIFEATURE *feature; - override = msi_dup_property( package, property ); + override = msi_dup_property( package->db, property ); if (!override) return FALSE; @@ -1688,7 +1758,7 @@ static BOOL process_overrides( MSIPACKAGE *package, int level ) ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED ); if (ret) - MSI_SetPropertyW( package, szPreselected, szOne ); + msi_set_property( package->db, szPreselected, szOne ); return ret; } @@ -1703,9 +1773,9 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) TRACE("Checking Install Level\n"); - level = msi_get_property_int(package, szlevel, 1); + level = msi_get_property_int(package->db, szlevel, 1); - if (!msi_get_property_int( package, szPreselected, 0 )) + if (!msi_get_property_int( package->db, szPreselected, 0 )) { LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) { @@ -1906,7 +1976,7 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; } -static LPWSTR msi_get_disk_file_version( LPCWSTR filename ) +static LPWSTR get_disk_file_version( LPCWSTR filename ) { static const WCHAR name_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; @@ -1944,7 +2014,36 @@ static LPWSTR msi_get_disk_file_version( LPCWSTR filename ) return strdupW( filever ); } -static UINT msi_check_file_install_states( MSIPACKAGE *package ) +static DWORD get_disk_file_size( LPCWSTR filename ) +{ + HANDLE file; + DWORD size; + + TRACE("%s\n", debugstr_w(filename)); + + file = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); + if (file == INVALID_HANDLE_VALUE) + return INVALID_FILE_SIZE; + + size = GetFileSize( file, NULL ); + CloseHandle( file ); + return size; +} + +static BOOL hash_matches( MSIFILE *file ) +{ + UINT r; + MSIFILEHASHINFO hash; + + hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); + r = MsiGetFileHashW( file->TargetPath, 0, &hash ); + if (r != ERROR_SUCCESS) + return FALSE; + + return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) ); +} + +static UINT set_file_install_states( MSIPACKAGE *package ) { LPWSTR file_version; MSIFILE *file; @@ -1952,6 +2051,7 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package ) LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry ) { MSICOMPONENT* comp = file->Component; + DWORD file_size; LPWSTR p; if (!comp) @@ -1975,38 +2075,43 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package ) TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath)); - /* don't check files of components that aren't installed */ - if (comp->Installed == INSTALLSTATE_UNKNOWN || - comp->Installed == INSTALLSTATE_ABSENT) - { - file->state = msifs_missing; /* assume files are missing */ - continue; - } - if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) { file->state = msifs_missing; comp->Cost += file->FileSize; continue; } - - if (file->Version && - (file_version = msi_get_disk_file_version( file->TargetPath ))) + if (file->Version && (file_version = get_disk_file_version( file->TargetPath ))) { - TRACE("new %s old %s\n", debugstr_w(file->Version), - debugstr_w(file_version)); - /* FIXME: seems like a bad way to compare version numbers */ - if (lstrcmpiW(file_version, file->Version)<0) + TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(file_version)); + + if (strcmpiW(file_version, file->Version) < 0) { file->state = msifs_overwrite; comp->Cost += file->FileSize; } else + { + TRACE("Destination file version equal or greater, not overwriting\n"); file->state = msifs_present; + } msi_free( file_version ); + continue; } - else + if ((file_size = get_disk_file_size( file->TargetPath )) != file->FileSize) + { + file->state = msifs_overwrite; + comp->Cost += file->FileSize - file_size; + continue; + } + if (file->hash.dwFileHashInfoSize && hash_matches( file )) + { + TRACE("File hashes match, not overwriting\n"); file->state = msifs_present; + continue; + } + file->state = msifs_overwrite; + comp->Cost += file->FileSize - file_size; } return ERROR_SUCCESS; @@ -2051,12 +2156,12 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) ACTION_GetComponentInstallStates(package); ACTION_GetFeatureInstallStates(package); - TRACE("File calculations\n"); - msi_check_file_install_states( package ); + TRACE("Calculating file install states\n"); + set_file_install_states( package ); - if (!process_overrides( package, msi_get_property_int( package, szlevel, 1 ) )) + if (!process_overrides( package, msi_get_property_int( package->db, szlevel, 1 ) )) { - TRACE("Evaluating Condition Table\n"); + TRACE("Evaluating feature conditions\n"); rc = MSI_DatabaseOpenViewW( package->db, ConditionQuery, &view ); if (rc == ERROR_SUCCESS) @@ -2064,29 +2169,29 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) rc = MSI_IterateRecords( view, NULL, ITERATE_CostFinalizeConditions, package ); msiobj_release( &view->hdr ); } + } + TRACE("Evaluating component conditions\n"); - TRACE("Enabling or Disabling Components\n"); - LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) + { + if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) { - if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE) - { - TRACE("Disabling component %s\n", debugstr_w(comp->Component)); - comp->Enabled = FALSE; - } - else - comp->Enabled = TRUE; + TRACE("Disabling component %s\n", debugstr_w(comp->Component)); + comp->Enabled = FALSE; } + else + comp->Enabled = TRUE; } - MSI_SetPropertyW(package,szCosting,szOne); + msi_set_property( package->db, szCosting, szOne ); /* set default run level if not set */ - level = msi_dup_property( package, szlevel ); + level = msi_dup_property( package->db, szlevel ); if (!level) - MSI_SetPropertyW(package,szlevel, szOne); + msi_set_property( package->db, szlevel, szOne ); msi_free(level); /* FIXME: check volume disk space */ - MSI_SetPropertyW(package, szOutOfDiskSpace, szZero); + msi_set_property( package->db, szOutOfDiskSpace, szZero ); return MSI_SetFeatureStates(package); } @@ -2220,7 +2325,7 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key switch (root) { case -1: - if (msi_get_property_int( package, szAllUsers, 0 )) + if (msi_get_property_int( package->db, szAllUsers, 0 )) { *root_key = HKEY_LOCAL_MACHINE; ret = szHLM; @@ -2364,12 +2469,8 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) uirow = MSI_CreateRecord(3); MSI_RecordSetStringW(uirow,2,deformated); MSI_RecordSetStringW(uirow,1,uikey); - - if (type == REG_SZ) + if (type == REG_SZ || type == REG_EXPAND_SZ) MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data); - else - MSI_RecordSetStringW(uirow,3,value); - ui_actiondata(package,szWriteRegistryValues,uirow); msiobj_release( &uirow->hdr ); @@ -2995,6 +3096,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) else MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL); } + comp->Action = comp->ActionRequest; /* UI stuff */ uirow = MSI_CreateRecord(3); @@ -3103,7 +3205,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) { LPCWSTR guid; guid = MSI_RecordGetString(row,1); - CLSIDFromString((LPWSTR)guid, &tl_struct.clsid); + CLSIDFromString((LPCWSTR)guid, &tl_struct.clsid); tl_struct.source = strdupW( file->TargetPath ); tl_struct.path = NULL; @@ -3204,7 +3306,7 @@ static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param ) ui_actiondata( package, szUnregisterTypeLibraries, row ); guid = MSI_RecordGetString( row, 1 ); - CLSIDFromString( (LPWSTR)guid, &libid ); + CLSIDFromString( (LPCWSTR)guid, &libid ); version = MSI_RecordGetInteger( row, 4 ); language = MSI_RecordGetInteger( row, 2 ); @@ -3610,17 +3712,17 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey) {'C','l','i','e','n','t','s',0}; static const WCHAR szColon[] = {':',0}; - buffer = msi_dup_property(package, INSTALLPROPERTY_PRODUCTNAMEW); + buffer = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW); msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTNAMEW, buffer); msi_free(buffer); - langid = msi_get_property_int(package, szProductLanguage, 0); + langid = msi_get_property_int(package->db, szProductLanguage, 0); msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid); /* FIXME */ msi_reg_set_val_dword(hkey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0); - buffer = msi_dup_property(package, szARPProductIcon); + buffer = msi_dup_property(package->db, szARPProductIcon); if (buffer) { LPWSTR path = build_icon_path(package,buffer); @@ -3629,7 +3731,7 @@ static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey) msi_free(buffer); } - buffer = msi_dup_property(package, szProductVersion); + buffer = msi_dup_property(package->db, szProductVersion); if (buffer) { DWORD verdword = msi_version_str_to_dword(buffer); @@ -3677,7 +3779,7 @@ static UINT msi_publish_upgrade_code(MSIPACKAGE *package) static const WCHAR szUpgradeCode[] = {'U','p','g','r','a','d','e','C','o','d','e',0}; - upgrade = msi_dup_property(package, szUpgradeCode); + upgrade = msi_dup_property(package->db, szUpgradeCode); if (!upgrade) return ERROR_SUCCESS; @@ -3730,34 +3832,80 @@ static BOOL msi_check_unpublish(MSIPACKAGE *package) return TRUE; } -static UINT msi_publish_patch(MSIPACKAGE *package, HKEY prodkey, HKEY hudkey) +static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey ) { + static const WCHAR szAllPatches[] = {'A','l','l','P','a','t','c','h','e','s',0}; WCHAR patch_squashed[GUID_SIZE]; - HKEY patches; + HKEY patches_key = NULL, product_patches_key; LONG res; - UINT r = ERROR_FUNCTION_FAILED; + MSIPATCHINFO *patch; + UINT r; + WCHAR *p, *all_patches = NULL; + DWORD len = 0; - res = RegCreateKeyExW(prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, - &patches, NULL); + res = RegCreateKeyExW( prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL ); if (res != ERROR_SUCCESS) return ERROR_FUNCTION_FAILED; - squash_guid(package->patch->patchcode, patch_squashed); + r = MSIREG_OpenUserDataProductPatchesKey( package->ProductCode, package->Context, &product_patches_key, TRUE ); + if (r != ERROR_SUCCESS) + goto done; - res = RegSetValueExW(patches, szPatches, 0, REG_MULTI_SZ, - (const BYTE *)patch_squashed, - (lstrlenW(patch_squashed) + 1) * sizeof(WCHAR)); + LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry ) + { + squash_guid( patch->patchcode, patch_squashed ); + len += strlenW( patch_squashed ) + 1; + } + + p = all_patches = msi_alloc( (len + 1) * sizeof(WCHAR) ); + if (!all_patches) + goto done; + + LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry ) + { + HKEY patch_key; + + squash_guid( patch->patchcode, p ); + p += strlenW( p ) + 1; + + res = RegSetValueExW( patches_key, patch_squashed, 0, REG_SZ, + (const BYTE *)patch->transforms, + (strlenW(patch->transforms) + 1) * sizeof(WCHAR) ); + if (res != ERROR_SUCCESS) + goto done; + + r = MSIREG_OpenUserDataPatchKey( patch->patchcode, package->Context, &patch_key, TRUE ); + if (r != ERROR_SUCCESS) + goto done; + + res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ, + (const BYTE *)patch->localfile, + (strlenW(patch->localfile) + 1) * sizeof(WCHAR) ); + RegCloseKey( patch_key ); + if (res != ERROR_SUCCESS) + goto done; + + res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL ); + RegCloseKey( patch_key ); + if (res != ERROR_SUCCESS) + goto done; + } + + all_patches[len] = 0; + res = RegSetValueExW( patches_key, szPatches, 0, REG_MULTI_SZ, + (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) ); if (res != ERROR_SUCCESS) goto done; - res = RegSetValueExW(patches, patch_squashed, 0, REG_SZ, - (const BYTE *)package->patch->transforms, - (lstrlenW(package->patch->transforms) + 1) * sizeof(WCHAR)); - if (res == ERROR_SUCCESS) - r = ERROR_SUCCESS; + res = RegSetValueExW( product_patches_key, szAllPatches, 0, REG_MULTI_SZ, + (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) ); + if (res != ERROR_SUCCESS) + r = ERROR_FUNCTION_FAILED; done: - RegCloseKey(patches); + RegCloseKey( product_patches_key ); + RegCloseKey( patches_key ); + msi_free( all_patches ); return r; } @@ -3791,9 +3939,9 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) if (rc != ERROR_SUCCESS) goto end; - if (package->patch) + if (!list_empty(&package->patches)) { - rc = msi_publish_patch(package, hukey, hudkey); + rc = msi_publish_patches(package, hukey); if (rc != ERROR_SUCCESS) goto end; } @@ -3836,10 +3984,10 @@ static WCHAR *get_ini_file_name( MSIPACKAGE *package, MSIRECORD *row ) { folder = resolve_folder( package, dirprop, FALSE, FALSE, TRUE, NULL ); if (!folder) - folder = msi_dup_property( package, dirprop ); + folder = msi_dup_property( package->db, dirprop ); } else - folder = msi_dup_property( package, szWindowsFolder ); + folder = msi_dup_property( package->db, szWindowsFolder ); if (!folder) { @@ -4152,21 +4300,16 @@ static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param) CloseHandle(info.hProcess); } - msi_free(FullName); - - /* the UI chunk */ uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, filename ); uipath = strdupW( file->TargetPath ); - p = strrchrW(uipath,'\\'); - if (p) - p[0]=0; - MSI_RecordSetStringW( uirow, 1, &p[1] ); - MSI_RecordSetStringW( uirow, 2, uipath); - ui_actiondata( package, szSelfRegModules, uirow); + if ((p = strrchrW( uipath,'\\' ))) *p = 0; + MSI_RecordSetStringW( uirow, 2, uipath ); + ui_actiondata( package, szSelfRegModules, uirow ); msiobj_release( &uirow->hdr ); - msi_free( uipath ); - /* FIXME: call ui_progress? */ + msi_free( FullName ); + msi_free( uipath ); return ERROR_SUCCESS; } @@ -4235,21 +4378,16 @@ static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param ) CloseHandle( pi.hProcess ); } - msi_free( cmdline ); - uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, filename ); uipath = strdupW( file->TargetPath ); - if ((p = strrchrW( uipath, '\\' ))) - { - *p = 0; - MSI_RecordSetStringW( uirow, 1, ++p ); - } + if ((p = strrchrW( uipath,'\\' ))) *p = 0; MSI_RecordSetStringW( uirow, 2, uipath ); ui_actiondata( package, szSelfUnregModules, uirow ); msiobj_release( &uirow->hdr ); - msi_free( uipath ); - /* FIXME call ui_progress? */ + msi_free( cmdline ); + msi_free( uipath ); return ERROR_SUCCESS; } @@ -4351,7 +4489,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) { size += sizeof(WCHAR); RegSetValueExW(hkey,feature->Feature,0,REG_SZ, - (LPBYTE)(feature->Feature_Parent ? feature->Feature_Parent : szEmpty),size); + (const BYTE*)(feature->Feature_Parent ? feature->Feature_Parent : szEmpty),size); } else { @@ -4384,6 +4522,7 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature) { UINT r; HKEY hkey; + MSIRECORD *uirow; TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature)); @@ -4403,6 +4542,11 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature) RegCloseKey(hkey); } + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, feature->Feature ); + ui_actiondata( package, szUnpublishFeatures, uirow ); + msiobj_release( &uirow->hdr ); + return ERROR_SUCCESS; } @@ -4423,11 +4567,10 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package) static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) { - LPWSTR prop, val, key; SYSTEMTIME systime; DWORD size, langid; - WCHAR date[9]; - LPWSTR buffer; + WCHAR date[9], *val, *buffer; + const WCHAR *prop, *key; static const WCHAR date_fmt[] = {'%','i','%','0','2','i','%','0','2','i',0}; static const WCHAR szWindowsInstaller[] = @@ -4445,43 +4588,84 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0}; static const WCHAR szProductVersion[] = {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; + static const WCHAR szDisplayVersion[] = + {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; + static const WCHAR szInstallSource[] = + {'I','n','s','t','a','l','l','S','o','u','r','c','e',0}; + static const WCHAR szARPAUTHORIZEDCDFPREFIX[] = + {'A','R','P','A','U','T','H','O','R','I','Z','E','D','C','D','F','P','R','E','F','I','X',0}; + static const WCHAR szAuthorizedCDFPrefix[] = + {'A','u','t','h','o','r','i','z','e','d','C','D','F','P','r','e','f','i','x',0}; + static const WCHAR szARPCONTACT[] = + {'A','R','P','C','O','N','T','A','C','T',0}; + static const WCHAR szContact[] = + {'C','o','n','t','a','c','t',0}; + static const WCHAR szARPCOMMENTS[] = + {'A','R','P','C','O','M','M','E','N','T','S',0}; + static const WCHAR szComments[] = + {'C','o','m','m','e','n','t','s',0}; static const WCHAR szProductName[] = {'P','r','o','d','u','c','t','N','a','m','e',0}; static const WCHAR szDisplayName[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; - static const WCHAR szDisplayVersion[] = - {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; + static const WCHAR szARPHELPLINK[] = + {'A','R','P','H','E','L','P','L','I','N','K',0}; + static const WCHAR szHelpLink[] = + {'H','e','l','p','L','i','n','k',0}; + static const WCHAR szARPHELPTELEPHONE[] = + {'A','R','P','H','E','L','P','T','E','L','E','P','H','O','N','E',0}; + static const WCHAR szHelpTelephone[] = + {'H','e','l','p','T','e','l','e','p','h','o','n','e',0}; + static const WCHAR szARPINSTALLLOCATION[] = + {'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0}; + static const WCHAR szInstallLocation[] = + {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0}; static const WCHAR szManufacturer[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0}; + static const WCHAR szPublisher[] = + {'P','u','b','l','i','s','h','e','r',0}; + static const WCHAR szARPREADME[] = + {'A','R','P','R','E','A','D','M','E',0}; + static const WCHAR szReadme[] = + {'R','e','a','d','M','e',0}; + static const WCHAR szARPSIZE[] = + {'A','R','P','S','I','Z','E',0}; + static const WCHAR szSize[] = + {'S','i','z','e',0}; + static const WCHAR szARPURLINFOABOUT[] = + {'A','R','P','U','R','L','I','N','F','O','A','B','O','U','T',0}; + static const WCHAR szURLInfoAbout[] = + {'U','R','L','I','n','f','o','A','b','o','u','t',0}; + static const WCHAR szARPURLUPDATEINFO[] = + {'A','R','P','U','R','L','U','P','D','A','T','E','I','N','F','O',0}; + static const WCHAR szURLUpdateInfo[] = + {'U','R','L','U','p','d','a','t','e','I','n','f','o',0}; - static const LPCSTR propval[] = { - "ARPAUTHORIZEDCDFPREFIX", "AuthorizedCDFPrefix", - "ARPCONTACT", "Contact", - "ARPCOMMENTS", "Comments", - "ProductName", "DisplayName", - "ProductVersion", "DisplayVersion", - "ARPHELPLINK", "HelpLink", - "ARPHELPTELEPHONE", "HelpTelephone", - "ARPINSTALLLOCATION", "InstallLocation", - "SourceDir", "InstallSource", - "Manufacturer", "Publisher", - "ARPREADME", "Readme", - "ARPSIZE", "Size", - "ARPURLINFOABOUT", "URLInfoAbout", - "ARPURLUPDATEINFO", "URLUpdateInfo", - NULL, + static const WCHAR *propval[] = { + szARPAUTHORIZEDCDFPREFIX, szAuthorizedCDFPrefix, + szARPCONTACT, szContact, + szARPCOMMENTS, szComments, + szProductName, szDisplayName, + szARPHELPLINK, szHelpLink, + szARPHELPTELEPHONE, szHelpTelephone, + szARPINSTALLLOCATION, szInstallLocation, + cszSourceDir, szInstallSource, + szManufacturer, szPublisher, + szARPREADME, szReadme, + szARPSIZE, szSize, + szARPURLINFOABOUT, szURLInfoAbout, + szARPURLUPDATEINFO, szURLUpdateInfo, + NULL }; - const LPCSTR *p = propval; + const WCHAR **p = propval; while (*p) { - prop = strdupAtoW(*p++); - key = strdupAtoW(*p++); - val = msi_dup_property(package, prop); + prop = *p++; + key = *p++; + val = msi_dup_property(package->db, prop); msi_reg_set_val_str(hkey, key, val); msi_free(val); - msi_free(key); - msi_free(prop); } msi_reg_set_val_dword(hkey, szWindowsInstaller, 1); @@ -4494,26 +4678,14 @@ static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) /* FIXME: Write real Estimated Size when we have it */ msi_reg_set_val_dword(hkey, szEstimatedSize, 0); - buffer = msi_dup_property(package, szProductName); - msi_reg_set_val_str(hkey, szDisplayName, buffer); - msi_free(buffer); - - buffer = msi_dup_property(package, cszSourceDir); - msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLSOURCEW, buffer); - msi_free(buffer); - - buffer = msi_dup_property(package, szManufacturer); - msi_reg_set_val_str(hkey, INSTALLPROPERTY_PUBLISHERW, buffer); - msi_free(buffer); - GetLocalTime(&systime); sprintfW(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay); msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLDATEW, date); - langid = msi_get_property_int(package, szProductLanguage, 0); + langid = msi_get_property_int(package->db, szProductLanguage, 0); msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid); - buffer = msi_dup_property(package, szProductVersion); + buffer = msi_dup_property(package->db, szProductVersion); msi_reg_set_val_str(hkey, szDisplayVersion, buffer); if (buffer) { @@ -4565,7 +4737,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) if (rc != ERROR_SUCCESS) goto done; - upgrade_code = msi_dup_property(package, szUpgradeCode); + upgrade_code = msi_dup_property(package->db, szUpgradeCode); if (upgrade_code) { MSIREG_OpenUpgradeCodesKey(upgrade_code, &upgrade, TRUE); @@ -4597,11 +4769,12 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) LPWSTR *features = NULL; BOOL full_uninstall = TRUE; MSIFEATURE *feature; + MSIPATCHINFO *patch; static const WCHAR szUpgradeCode[] = {'U','p','g','r','a','d','e','C','o','d','e',0}; - remove = msi_dup_property(package, szRemove); + remove = msi_dup_property(package->db, szRemove); if (!remove) return ERROR_SUCCESS; @@ -4642,13 +4815,18 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) MSIREG_DeleteUserFeaturesKey(package->ProductCode); } - upgrade = msi_dup_property(package, szUpgradeCode); + upgrade = msi_dup_property(package->db, szUpgradeCode); if (upgrade) { MSIREG_DeleteUserUpgradeCodesKey(upgrade); msi_free(upgrade); } + LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry) + { + MSIREG_DeleteUserDataPatchKey(patch->patchcode, package->Context); + } + done: msi_free(remove); msi_free(features); @@ -4809,7 +4987,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) goto end; } - productid = msi_dup_property( package, INSTALLPROPERTY_PRODUCTIDW ); + productid = msi_dup_property( package->db, INSTALLPROPERTY_PRODUCTIDW ); if (!productid) goto end; @@ -4820,7 +4998,7 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) for( i = 0; szPropKeys[i][0]; i++ ) { - buffer = msi_dup_property( package, szPropKeys[i] ); + buffer = msi_dup_property( package->db, szPropKeys[i] ); msi_reg_set_val_str( hkey, szRegKeys[i], buffer ); msi_free( buffer ); } @@ -5162,10 +5340,11 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param) { MSIPACKAGE *package = param; MSICOMPONENT *comp; + MSIRECORD *uirow; SC_HANDLE scm = NULL, service = NULL; LPCWSTR component, *vector = NULL; - LPWSTR name, args; - DWORD event, numargs; + LPWSTR name, args, display_name = NULL; + DWORD event, numargs, len; UINT r = ERROR_FUNCTION_FAILED; component = MSI_RecordGetString(rec, 6); @@ -5198,6 +5377,14 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param) goto done; } + len = 0; + if (!GetServiceDisplayNameW( scm, name, NULL, &len ) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if ((display_name = msi_alloc( ++len * sizeof(WCHAR )))) + GetServiceDisplayNameW( scm, name, display_name, &len ); + } + service = OpenServiceW(scm, name, SERVICE_START); if (!service) { @@ -5217,12 +5404,19 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param) r = ERROR_SUCCESS; done: + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, display_name ); + MSI_RecordSetStringW( uirow, 2, name ); + ui_actiondata( package, szStartServices, uirow ); + msiobj_release( &uirow->hdr ); + CloseServiceHandle(service); CloseServiceHandle(scm); msi_free(name); msi_free(args); msi_free(vector); + msi_free(display_name); return r; } @@ -5335,9 +5529,11 @@ static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; MSICOMPONENT *comp; + MSIRECORD *uirow; LPCWSTR component; - LPWSTR name; - DWORD event; + LPWSTR name = NULL, display_name = NULL; + DWORD event, len; + SC_HANDLE scm; event = MSI_RecordGetInteger( rec, 3 ); if (!(event & msidbServiceControlEventStop)) @@ -5356,10 +5552,34 @@ static UINT ITERATE_StopService( MSIRECORD *rec, LPVOID param ) } comp->Action = INSTALLSTATE_ABSENT; + scm = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT ); + if (!scm) + { + ERR("Failed to open the service control manager\n"); + goto done; + } + + len = 0; + if (!GetServiceDisplayNameW( scm, name, NULL, &len ) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if ((display_name = msi_alloc( ++len * sizeof(WCHAR )))) + GetServiceDisplayNameW( scm, name, display_name, &len ); + } + CloseServiceHandle( scm ); + deformat_string( package, MSI_RecordGetString( rec, 2 ), &name ); stop_service( name ); - msi_free( name ); +done: + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, display_name ); + MSI_RecordSetStringW( uirow, 2, name ); + ui_actiondata( package, szStopServices, uirow ); + msiobj_release( &uirow->hdr ); + + msi_free( name ); + msi_free( display_name ); return ERROR_SUCCESS; } @@ -6749,19 +6969,19 @@ static UINT ACTION_ValidateProductID( MSIPACKAGE *package ) LPWSTR key, template, id; UINT r = ERROR_SUCCESS; - id = msi_dup_property( package, szProductID ); + id = msi_dup_property( package->db, szProductID ); if (id) { msi_free( id ); return ERROR_SUCCESS; } - template = msi_dup_property( package, szPIDTemplate ); - key = msi_dup_property( package, szPIDKEY ); + template = msi_dup_property( package->db, szPIDTemplate ); + key = msi_dup_property( package->db, szPIDKEY ); if (key && template) { FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) ); - r = MSI_SetPropertyW( package, szProductID, key ); + r = msi_set_property( package->db, szProductID, key ); } msi_free( template ); msi_free( key ); @@ -6780,7 +7000,7 @@ static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package ) static const WCHAR szAvailableFreeReg[] = {'A','V','A','I','L','A','B','L','E','F','R','E','E','R','E','G',0}; MSIRECORD *uirow; - int space = msi_get_property_int( package, szAvailableFreeReg, 0 ); + int space = msi_get_property_int( package->db, szAvailableFreeReg, 0 ); TRACE("%p %d kilobytes\n", package, space); @@ -6804,6 +7024,40 @@ static UINT ACTION_InstallAdminPackage( MSIPACKAGE *package ) return ERROR_SUCCESS; } +static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) +{ + UINT r, count; + MSIQUERY *view; + + static const WCHAR driver_query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + 'O','D','B','C','D','r','i','v','e','r',0 }; + + static const WCHAR translator_query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + 'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 }; + + r = MSI_DatabaseOpenViewW( package->db, driver_query, &view ); + if (r == ERROR_SUCCESS) + { + count = 0; + r = MSI_IterateRecords( view, &count, NULL, package ); + msiobj_release( &view->hdr ); + if (count) FIXME("ignored %u rows in ODBCDriver table\n", count); + } + + r = MSI_DatabaseOpenViewW( package->db, translator_query, &view ); + if (r == ERROR_SUCCESS) + { + count = 0; + r = MSI_IterateRecords( view, &count, NULL, package ); + msiobj_release( &view->hdr ); + if (count) FIXME("ignored %u rows in ODBCTranslator table\n", count); + } + + return ERROR_SUCCESS; +} + static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table ) { @@ -6890,36 +7144,6 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table ); } -static UINT ACTION_SetODBCFolders( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 }; - return msi_unimplemented_action_stub( package, "SetODBCFolders", table ); -} - -static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'A','p','p','I','d',0 }; - return msi_unimplemented_action_stub( package, "UnregisterClassInfo", table ); -} - -static UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'E','x','t','e','n','s','i','o','n',0 }; - return msi_unimplemented_action_stub( package, "UnregisterExtensionInfo", table ); -} - -static UINT ACTION_UnregisterMIMEInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'M','I','M','E',0 }; - return msi_unimplemented_action_stub( package, "UnregisterMIMEInfo", table ); -} - -static UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package ) -{ - static const WCHAR table[] = { 'P','r','o','g','I','d',0 }; - return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table ); -} - typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*); static const struct @@ -7171,7 +7395,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0}; - MSI_SetPropertyW(package, szAction, szInstall); + msi_set_property( package->db, szAction, szInstall ); package->script->InWhatSequence = SEQUENCE_INSTALL; @@ -7216,10 +7440,10 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, msi_apply_transforms( package ); msi_apply_patches( package ); - if (!szCommandLine && msi_get_property_int( package, szInstalled, 0 )) + if (!szCommandLine && msi_get_property_int( package->db, szInstalled, 0 )) { TRACE("setting reinstall property\n"); - MSI_SetPropertyW( package, szReinstall, szAll ); + msi_set_property( package->db, szReinstall, szAll ); } /* properties may have been added by a transform */ diff --git a/dll/win32/msi/appsearch.c b/dll/win32/msi/appsearch.c index 12c741178e3..336bfcae0f8 100644 --- a/dll/win32/msi/appsearch.c +++ b/dll/win32/msi/appsearch.c @@ -929,7 +929,8 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU 'D','r','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; - LPWSTR parentName = NULL, parent = NULL; + LPWSTR parent = NULL; + LPCWSTR parentName; WCHAR path[MAX_PATH]; WCHAR expanded[MAX_PATH]; MSIRECORD *row; @@ -949,14 +950,15 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU } /* check whether parent is set */ - parentName = msi_dup_record_field(row,2); + parentName = MSI_RecordGetString(row, 2); if (parentName) { MSISIGNATURE parentSig; rc = ACTION_AppSearchSigName(package, parentName, &parentSig, &parent); ACTION_FreeSignature(&parentSig); - msi_free(parentName); + if (!parent) + return ERROR_SUCCESS; } sz = MAX_PATH; @@ -1041,7 +1043,10 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) r = ACTION_AppSearchSigName(package, sigName, &sig, &value); if (value) { - MSI_SetPropertyW(package, propName, value); + r = msi_set_property( package->db, propName, value ); + if (r == ERROR_SUCCESS && !strcmpW( propName, cszSourceDir )) + msi_reset_folders( package, TRUE ); + msi_free(value); } ACTION_FreeSignature(&sig); @@ -1064,6 +1069,14 @@ UINT ACTION_AppSearch(MSIPACKAGE *package) MSIQUERY *view = NULL; UINT r; + if (check_unique_action(package, szAppSearch)) + { + TRACE("Skipping AppSearch action: already done in UI sequence\n"); + return ERROR_SUCCESS; + } + else + register_unique_action(package, szAppSearch); + r = MSI_OpenQuery( package->db, &view, query ); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; @@ -1092,7 +1105,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) if (value) { TRACE("Found signature %s\n", debugstr_w(signature)); - MSI_SetPropertyW(package, success, szOne); + msi_set_property(package->db, success, szOne); msi_free(value); r = ERROR_NO_MORE_ITEMS; } @@ -1111,6 +1124,14 @@ UINT ACTION_CCPSearch(MSIPACKAGE *package) MSIQUERY *view = NULL; UINT r; + if (check_unique_action(package, szCCPSearch)) + { + TRACE("Skipping AppSearch action: already done in UI sequence\n"); + return ERROR_SUCCESS; + } + else + register_unique_action(package, szCCPSearch); + r = MSI_OpenQuery(package->db, &view, query); if (r != ERROR_SUCCESS) return ERROR_SUCCESS; diff --git a/dll/win32/msi/automation.c b/dll/win32/msi/automation.c index f935a64397d..d6ef5c98781 100644 --- a/dll/win32/msi/automation.c +++ b/dll/win32/msi/automation.c @@ -167,7 +167,7 @@ static HRESULT create_automation_object(MSIHANDLE msiHandle, IUnknown *pUnkOuter if( pUnkOuter ) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AutomationObject)+sizetPrivateData); + object = msi_alloc_zero( sizeof(AutomationObject) + sizetPrivateData ); /* Set all the VTable references */ object->lpVtbl = &AutomationObject_Vtbl; @@ -184,7 +184,7 @@ static HRESULT create_automation_object(MSIHANDLE msiHandle, IUnknown *pUnkOuter object->iTypeInfo = NULL; hr = load_type_info((IDispatch *)object, &object->iTypeInfo, clsid, 0x0); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, object); + msi_free( object ); return hr; } @@ -203,7 +203,7 @@ static HRESULT create_list_enumerator(IUnknown *pUnkOuter, LPVOID *ppObj, Automa if( pUnkOuter ) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ListEnumerator)); + object = msi_alloc_zero( sizeof(ListEnumerator) ); /* Set all the VTable references */ object->lpVtbl = &ListEnumerator_Vtbl; @@ -288,7 +288,7 @@ static ULONG WINAPI AutomationObject_Release(IDispatch* iface) if (This->funcFree) This->funcFree(This); ITypeInfo_Release(This->iTypeInfo); MsiCloseHandle(This->msiHandle); - HeapFree(GetProcessHeap(), 0, This); + msi_free(This); } return ref; @@ -607,7 +607,7 @@ static ULONG WINAPI ListEnumerator_Release(IEnumVARIANT* iface) if (!ref) { if (This->pObj) IDispatch_Release((IDispatch *)This->pObj); - HeapFree(GetProcessHeap(), 0, This); + msi_free(This); } return ref; @@ -1043,7 +1043,7 @@ static void WINAPI ListImpl_Free(AutomationObject *This) for (idx=0; idxulCount; idx++) VariantClear(&data->pVars[idx]); - HeapFree(GetProcessHeap(), 0, data->pVars); + msi_free(data->pVars); } static HRESULT WINAPI ViewImpl_Invoke( diff --git a/dll/win32/msi/classes.c b/dll/win32/msi/classes.c index acd8429bec4..22d11c1441c 100644 --- a/dll/win32/msi/classes.c +++ b/dll/win32/msi/classes.c @@ -18,15 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* actions handled in this module +/* Actions handled in this module: + * * RegisterClassInfo * RegisterProgIdInfo * RegisterExtensionInfo * RegisterMIMEInfo - * UnRegisterClassInfo (TODO) - * UnRegisterProgIdInfo (TODO) - * UnRegisterExtensionInfo (TODO) - * UnRegisterMIMEInfo (TODO) + * UnregisterClassInfo + * UnregisterProgIdInfo + * UnregisterExtensionInfo + * UnregisterMIMEInfo */ #include @@ -343,7 +344,7 @@ static MSIEXTENSION *load_given_extension( MSIPACKAGE *package, LPCWSTR extensio static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row ) { - LPCWSTR buffer; + LPCWSTR extension; MSIMIME *mt; /* fill in the data */ @@ -355,8 +356,9 @@ static MSIMIME *load_mime( MSIPACKAGE* package, MSIRECORD *row ) mt->ContentType = msi_dup_record_field( row, 1 ); TRACE("loading mime %s\n", debugstr_w(mt->ContentType)); - buffer = MSI_RecordGetString( row, 2 ); - mt->Extension = load_given_extension( package, buffer ); + extension = MSI_RecordGetString( row, 2 ); + mt->Extension = load_given_extension( package, extension ); + mt->suffix = strdupW( extension ); mt->clsid = msi_dup_record_field( row, 3 ); mt->Class = load_given_class( package, mt->clsid ); @@ -720,6 +722,25 @@ static void mark_progid_for_install( MSIPACKAGE* package, MSIPROGID *progid ) } } +static void mark_progid_for_uninstall( MSIPACKAGE *package, MSIPROGID *progid ) +{ + MSIPROGID *child; + + if (!progid) + return; + + if (!progid->InstallMe) + return; + + progid->InstallMe = FALSE; + + LIST_FOR_EACH_ENTRY( child, &package->progids, MSIPROGID, entry ) + { + if (child->Parent == progid) + mark_progid_for_uninstall( package, child ); + } +} + static void mark_mime_for_install( MSIMIME *mime ) { if (!mime) @@ -727,9 +748,15 @@ static void mark_mime_for_install( MSIMIME *mime ) mime->InstallMe = TRUE; } +static void mark_mime_for_uninstall( MSIMIME *mime ) +{ + if (!mime) + return; + mime->InstallMe = FALSE; +} + static UINT register_appid(const MSIAPPID *appid, LPCWSTR app ) { - static const WCHAR szAppID[] = { 'A','p','p','I','D',0 }; static const WCHAR szRemoteServerName[] = {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0}; static const WCHAR szLocalService[] = @@ -776,24 +803,13 @@ static UINT register_appid(const MSIAPPID *appid, LPCWSTR app ) UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) { - /* - * Again I am assuming the words, "Whose key file represents" when referring - * to a Component as to meaning that Components KeyPath file - */ - - UINT rc; - MSIRECORD *uirow; - static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; - static const WCHAR szProgID[] = { 'P','r','o','g','I','D',0 }; - static const WCHAR szVIProgID[] = { 'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0 }; - static const WCHAR szAppID[] = { 'A','p','p','I','D',0 }; static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0}; + MSIRECORD *uirow; HKEY hkey,hkey2,hkey3; MSICLASS *cls; load_classes_and_such(package); - rc = RegCreateKeyW(HKEY_CLASSES_ROOT,szCLSID,&hkey); - if (rc != ERROR_SUCCESS) + if (RegCreateKeyW(HKEY_CLASSES_ROOT, szCLSID, &hkey) != ERROR_SUCCESS) return ERROR_FUNCTION_FAILED; LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry ) @@ -812,16 +828,21 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) if (!feature) continue; - /* - * MSDN says that these are based on Feature not on Component. - */ if (feature->ActionRequest != INSTALLSTATE_LOCAL && feature->ActionRequest != INSTALLSTATE_ADVERTISED ) { - TRACE("Feature %s not scheduled for installation, skipping regstration of class %s\n", + TRACE("Feature %s not scheduled for installation, skipping registration of class %s\n", debugstr_w(feature->Feature), debugstr_w(cls->clsid)); continue; } + feature->Action = feature->ActionRequest; + + file = get_loaded_file( package, comp->KeyPath ); + if (!file) + { + TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid)); + continue; + } TRACE("Registering class %s (%p)\n", debugstr_w(cls->clsid), cls); @@ -834,12 +855,6 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) msi_reg_set_val_str( hkey2, NULL, cls->Description ); RegCreateKeyW( hkey2, cls->Context, &hkey3 ); - file = get_loaded_file( package, comp->KeyPath ); - if (!file) - { - TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid)); - continue; - } /* * FIXME: Implement install on demand (advertised components). @@ -887,35 +902,18 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) if (cls->AppID) { MSIAPPID *appid = cls->AppID; - msi_reg_set_val_str( hkey2, szAppID, appid->AppID ); - register_appid( appid, cls->Description ); } if (cls->IconPath) - { - static const WCHAR szDefaultIcon[] = - {'D','e','f','a','u','l','t','I','c','o','n',0}; - msi_reg_set_subkey_val( hkey2, szDefaultIcon, NULL, cls->IconPath ); - } if (cls->DefInprocHandler) - { - static const WCHAR szInproc[] = - {'I','n','p','r','o','c','H','a','n','d','l','e','r',0}; - - msi_reg_set_subkey_val( hkey2, szInproc, NULL, cls->DefInprocHandler ); - } + msi_reg_set_subkey_val( hkey2, szInprocHandler, NULL, cls->DefInprocHandler ); if (cls->DefInprocHandler32) - { - static const WCHAR szInproc32[] = - {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; - - msi_reg_set_subkey_val( hkey2, szInproc32, NULL, cls->DefInprocHandler32 ); - } + msi_reg_set_subkey_val( hkey2, szInprocHandler32, NULL, cls->DefInprocHandler32 ); RegCloseKey(hkey2); @@ -947,14 +945,92 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package) } uirow = MSI_CreateRecord(1); - MSI_RecordSetStringW( uirow, 1, cls->clsid ); ui_actiondata(package,szRegisterClassInfo,uirow); msiobj_release(&uirow->hdr); } RegCloseKey(hkey); - return rc; + return ERROR_SUCCESS; +} + +UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package ) +{ + static const WCHAR szFileType[] = {'F','i','l','e','T','y','p','e','\\',0}; + MSIRECORD *uirow; + MSICLASS *cls; + HKEY hkey, hkey2; + + load_classes_and_such( package ); + if (RegOpenKeyW( HKEY_CLASSES_ROOT, szCLSID, &hkey ) != ERROR_SUCCESS) + return ERROR_SUCCESS; + + LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry ) + { + MSIFEATURE *feature; + MSICOMPONENT *comp; + LPWSTR filetype; + LONG res; + + comp = cls->Component; + if (!comp) + continue; + + feature = cls->Feature; + if (!feature) + continue; + + if (feature->ActionRequest != INSTALLSTATE_ABSENT) + { + TRACE("Feature %s not scheduled for removal, skipping unregistration of class %s\n", + debugstr_w(feature->Feature), debugstr_w(cls->clsid)); + continue; + } + feature->Action = feature->ActionRequest; + + TRACE("Unregistering class %s (%p)\n", debugstr_w(cls->clsid), cls); + + cls->Installed = FALSE; + mark_progid_for_uninstall( package, cls->ProgID ); + + res = RegDeleteTreeW( hkey, cls->clsid ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete class key %d\n", res); + + if (cls->AppID) + { + res = RegOpenKeyW( HKEY_CLASSES_ROOT, szAppID, &hkey2 ); + if (res == ERROR_SUCCESS) + { + res = RegDeleteKeyW( hkey2, cls->AppID->AppID ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete appid key %d\n", res); + RegCloseKey( hkey2 ); + } + } + if (cls->FileTypeMask) + { + filetype = msi_alloc( (strlenW( szFileType ) + strlenW( cls->clsid ) + 1) * sizeof(WCHAR) ); + if (filetype) + { + strcpyW( filetype, szFileType ); + strcatW( filetype, cls->clsid ); + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, filetype ); + msi_free( filetype ); + + if (res != ERROR_SUCCESS) + WARN("Failed to delete file type %d\n", res); + } + } + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, cls->clsid ); + ui_actiondata( package, szUnregisterClassInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + RegCloseKey( hkey ); + return ERROR_SUCCESS; } static LPCWSTR get_clsid_of_progid( const MSIPROGID *progid ) @@ -972,11 +1048,7 @@ static LPCWSTR get_clsid_of_progid( const MSIPROGID *progid ) static UINT register_progid( const MSIPROGID* progid ) { - static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 }; - static const WCHAR szDefaultIcon[] = - {'D','e','f','a','u','l','t','I','c','o','n',0}; - static const WCHAR szCurVer[] = - {'C','u','r','V','e','r',0}; + static const WCHAR szCurVer[] = {'C','u','r','V','e','r',0}; HKEY hkey = 0; UINT rc; @@ -1041,6 +1113,41 @@ UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package) return ERROR_SUCCESS; } +UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package ) +{ + MSIPROGID *progid; + MSIRECORD *uirow; + LONG res; + + load_classes_and_such( package ); + + LIST_FOR_EACH_ENTRY( progid, &package->progids, MSIPROGID, entry ) + { + /* check if this progid is to be removed */ + if (progid->Class && !progid->Class->Installed) + progid->InstallMe = FALSE; + + if (progid->InstallMe) + { + TRACE("progid %s not scheduled to be removed\n", debugstr_w(progid->ProgID)); + continue; + } + + TRACE("Unregistering progid %s\n", debugstr_w(progid->ProgID)); + + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid->ProgID ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete progid key %d\n", res); + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, progid->ProgID ); + ui_actiondata( package, szUnregisterProgIdInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + return ERROR_SUCCESS; +} + static UINT register_verb(MSIPACKAGE *package, LPCWSTR progid, MSICOMPONENT* component, const MSIEXTENSION* extension, MSIVERB* verb, INT* Sequence ) @@ -1122,10 +1229,11 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) { static const WCHAR szContentType[] = {'C','o','n','t','e','n','t',' ','T','y','p','e',0 }; - HKEY hkey; + HKEY hkey = NULL; MSIEXTENSION *ext; MSIRECORD *uirow; BOOL install_on_demand = TRUE; + LONG res; load_classes_and_such(package); @@ -1157,6 +1265,7 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) debugstr_w(feature->Feature), debugstr_w(ext->Extension)); continue; } + feature->Action = feature->ActionRequest; TRACE("Registering extension %s (%p)\n", debugstr_w(ext->Extension), ext); @@ -1170,12 +1279,16 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) mark_mime_for_install(ext->Mime); - extension = msi_alloc( (lstrlenW( ext->Extension ) + 2)*sizeof(WCHAR) ); - extension[0] = '.'; - lstrcpyW(extension+1,ext->Extension); - - RegCreateKeyW(HKEY_CLASSES_ROOT,extension,&hkey); - msi_free( extension ); + extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) ); + if (extension) + { + extension[0] = '.'; + strcpyW( extension + 1, ext->Extension ); + res = RegCreateKeyW( HKEY_CLASSES_ROOT, extension, &hkey ); + msi_free( extension ); + if (res != ERROR_SUCCESS) + WARN("Failed to create extension key %d\n", res); + } if (ext->Mime) msi_reg_set_val_str( hkey, szContentType, ext->Mime->ContentType ); @@ -1225,6 +1338,86 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package) return ERROR_SUCCESS; } +UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package ) +{ + MSIEXTENSION *ext; + MSIRECORD *uirow; + LONG res; + + load_classes_and_such( package ); + + LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry ) + { + LPWSTR extension; + MSIFEATURE *feature; + + if (!ext->Component) + continue; + + feature = ext->Feature; + if (!feature) + continue; + + if (feature->ActionRequest != INSTALLSTATE_ABSENT) + { + TRACE("Feature %s not scheduled for removal, skipping unregistration of extension %s\n", + debugstr_w(feature->Feature), debugstr_w(ext->Extension)); + continue; + } + + TRACE("Unregistering extension %s\n", debugstr_w(ext->Extension)); + + ext->Installed = FALSE; + + if (ext->ProgID && !list_empty( &ext->verbs )) + mark_progid_for_uninstall( package, ext->ProgID ); + + mark_mime_for_uninstall( ext->Mime ); + + extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) ); + if (extension) + { + extension[0] = '.'; + strcpyW( extension + 1, ext->Extension ); + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, extension ); + msi_free( extension ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete extension key %d\n", res); + } + + if (ext->ProgID || ext->ProgIDText) + { + static const WCHAR shellW[] = {'\\','s','h','e','l','l',0}; + LPCWSTR progid; + LPWSTR progid_shell; + + if (ext->ProgID) + progid = ext->ProgID->ProgID; + else + progid = ext->ProgIDText; + + progid_shell = msi_alloc( (strlenW( progid ) + strlenW( shellW ) + 1) * sizeof(WCHAR) ); + if (progid_shell) + { + strcpyW( progid_shell, progid ); + strcatW( progid_shell, shellW ); + res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid_shell ); + msi_free( progid_shell ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete shell key %d\n", res); + RegDeleteKeyW( HKEY_CLASSES_ROOT, progid ); + } + } + + uirow = MSI_CreateRecord( 1 ); + MSI_RecordSetStringW( uirow, 1, ext->Extension ); + ui_actiondata( package, szUnregisterExtensionInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + return ERROR_SUCCESS; +} + UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) { static const WCHAR szExten[] = @@ -1237,11 +1430,6 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) LIST_FOR_EACH_ENTRY( mt, &package->mimes, MSIMIME, entry ) { LPWSTR extension; - LPCWSTR exten; - LPCWSTR mime; - static const WCHAR fmt[] = - {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\', - 'C','o','n','t','e','n','t',' ','T','y','p','e','\\', '%','s',0}; LPWSTR key; /* @@ -1254,33 +1442,80 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package) if (!mt->InstallMe) { - TRACE("MIME %s not scheduled to be installed\n", - debugstr_w(mt->ContentType)); + TRACE("MIME %s not scheduled to be installed\n", debugstr_w(mt->ContentType)); continue; } - - mime = mt->ContentType; - exten = mt->Extension->Extension; - extension = msi_alloc( (lstrlenW( exten ) + 2)*sizeof(WCHAR) ); - extension[0] = '.'; - lstrcpyW(extension+1,exten); + TRACE("Registering MIME type %s\n", debugstr_w(mt->ContentType)); - key = msi_alloc( (strlenW(mime)+strlenW(fmt)+1) * sizeof(WCHAR) ); - sprintfW(key,fmt,mime); - msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szExten, extension ); + extension = msi_alloc( (strlenW( mt->Extension->Extension ) + 2) * sizeof(WCHAR) ); + key = msi_alloc( (strlenW( mt->ContentType ) + strlenW( szMIMEDatabase ) + 1) * sizeof(WCHAR) ); - msi_free(extension); - msi_free(key); + if (extension && key) + { + extension[0] = '.'; + strcpyW( extension + 1, mt->Extension->Extension ); - if (mt->clsid) - FIXME("Handle non null for field 3\n"); + strcpyW( key, szMIMEDatabase ); + strcatW( key, mt->ContentType ); + msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szExten, extension ); - uirow = MSI_CreateRecord(2); - MSI_RecordSetStringW(uirow,1,mt->ContentType); - MSI_RecordSetStringW(uirow,2,exten); - ui_actiondata(package,szRegisterMIMEInfo,uirow); - msiobj_release(&uirow->hdr); + if (mt->clsid) + msi_reg_set_subkey_val( HKEY_CLASSES_ROOT, key, szCLSID, mt->clsid ); + } + msi_free( extension ); + msi_free( key ); + + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, mt->ContentType ); + MSI_RecordSetStringW( uirow, 2, mt->suffix ); + ui_actiondata( package, szRegisterMIMEInfo, uirow ); + msiobj_release( &uirow->hdr ); + } + + return ERROR_SUCCESS; +} + +UINT ACTION_UnregisterMIMEInfo( MSIPACKAGE *package ) +{ + MSIRECORD *uirow; + MSIMIME *mime; + + load_classes_and_such( package ); + + LIST_FOR_EACH_ENTRY( mime, &package->mimes, MSIMIME, entry ) + { + LONG res; + LPWSTR mime_key; + + mime->InstallMe = (mime->InstallMe || + (mime->Class && mime->Class->Installed) || + (mime->Extension && mime->Extension->Installed)); + + if (mime->InstallMe) + { + TRACE("MIME %s not scheduled to be removed\n", debugstr_w(mime->ContentType)); + continue; + } + + TRACE("Unregistering MIME type %s\n", debugstr_w(mime->ContentType)); + + mime_key = msi_alloc( (strlenW( szMIMEDatabase ) + strlenW( mime->ContentType ) + 1) * sizeof(WCHAR) ); + if (mime_key) + { + strcpyW( mime_key, szMIMEDatabase ); + strcatW( mime_key, mime->ContentType ); + res = RegDeleteKeyW( HKEY_CLASSES_ROOT, mime_key ); + if (res != ERROR_SUCCESS) + WARN("Failed to delete MIME key %d\n", res); + msi_free( mime_key ); + } + + uirow = MSI_CreateRecord( 2 ); + MSI_RecordSetStringW( uirow, 1, mime->ContentType ); + MSI_RecordSetStringW( uirow, 2, mime->suffix ); + ui_actiondata( package, szUnregisterMIMEInfo, uirow ); + msiobj_release( &uirow->hdr ); } return ERROR_SUCCESS; diff --git a/dll/win32/msi/cond.tab.c b/dll/win32/msi/cond.tab.c index 5449d99fdab..2b10d209be6 100644 --- a/dll/win32/msi/cond.tab.c +++ b/dll/win32/msi/cond.tab.c @@ -1989,7 +1989,7 @@ yyreduce: COND_input* cond = (COND_input*) info; UINT len; - (yyval.string) = msi_dup_property( cond->package, (yyvsp[(1) - (1)].string) ); + (yyval.string) = msi_dup_property( cond->package->db, (yyvsp[(1) - (1)].string) ); if ((yyval.string)) { len = (lstrlenW((yyval.string)) + 1) * sizeof (WCHAR); diff --git a/dll/win32/msi/cond.y b/dll/win32/msi/cond.y index f3db635a10a..9a7a16d67df 100644 --- a/dll/win32/msi/cond.y +++ b/dll/win32/msi/cond.y @@ -347,7 +347,7 @@ symbol_s: COND_input* cond = (COND_input*) info; UINT len; - $$ = msi_dup_property( cond->package, $1 ); + $$ = msi_dup_property( cond->package->db, $1 ); if ($$) { len = (lstrlenW($$) + 1) * sizeof (WCHAR); diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c index 584c0507c53..5a1787f7d15 100644 --- a/dll/win32/msi/custom.c +++ b/dll/win32/msi/custom.c @@ -163,17 +163,17 @@ static void set_deferred_action_props(MSIPACKAGE *package, LPWSTR deferred_data) end = strstrW(beg, sep); *end = '\0'; - MSI_SetPropertyW(package, szCustomActionData, beg); + msi_set_property(package->db, szCustomActionData, beg); beg = end + 3; end = strstrW(beg, sep); *end = '\0'; - MSI_SetPropertyW(package, szUserSID, beg); + msi_set_property(package->db, szUserSID, beg); beg = end + 3; end = strchrW(beg, ']'); *end = '\0'; - MSI_SetPropertyW(package, szProductCode, beg); + msi_set_property(package->db, szProductCode, beg); } UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL execute) @@ -231,9 +231,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL } if (!execute) { - LPWSTR actiondata = msi_dup_property(package, action); - LPWSTR usersid = msi_dup_property(package, szUserSID); - LPWSTR prodcode = msi_dup_property(package, szProductCode); + LPWSTR actiondata = msi_dup_property(package->db, action); + LPWSTR usersid = msi_dup_property(package->db, szUserSID); + LPWSTR prodcode = msi_dup_property(package->db, szProductCode); LPWSTR deferred = msi_get_deferred_action(action, actiondata, usersid, prodcode); if (type & msidbCustomActionTypeCommit) @@ -256,7 +256,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL } else { - LPWSTR actiondata = msi_dup_property( package, action ); + LPWSTR actiondata = msi_dup_property( package->db, action ); switch (script) { @@ -276,9 +276,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL if (deferred_data) set_deferred_action_props(package, deferred_data); else if (actiondata) - MSI_SetPropertyW(package, szCustomActionData, actiondata); + msi_set_property(package->db, szCustomActionData, actiondata); else - MSI_SetPropertyW(package, szCustomActionData, szEmpty); + msi_set_property(package->db, szCustomActionData, szEmpty); msi_free(actiondata); } @@ -327,7 +327,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL break; deformat_string(package,target,&deformated); - rc = MSI_SetPropertyW(package,source,deformated); + rc = msi_set_property( package->db, source, deformated ); + if (rc == ERROR_SUCCESS && !strcmpW( source, cszSourceDir )) + msi_reset_folders( package, TRUE ); msi_free(deformated); break; case 37: /* JScript/VBScript text stored in target column. */ @@ -376,7 +378,7 @@ static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source, DWORD sz = MAX_PATH; UINT r; - if (MSI_GetPropertyW(package, cszTempFolder, fmt, &sz) != ERROR_SUCCESS) + if (msi_get_property(package->db, cszTempFolder, fmt, &sz) != ERROR_SUCCESS) GetTempPathW(MAX_PATH, fmt); if (GetTempFileNameW(fmt, szMsi, 0, tmp_file) == 0) @@ -864,7 +866,7 @@ static UINT HANDLE_CustomType23(MSIPACKAGE *package, LPCWSTR source, UINT r; size = MAX_PATH; - MSI_GetPropertyW(package, cszSourceDir, package_path, &size); + msi_get_property(package->db, cszSourceDir, package_path, &size); lstrcatW(package_path, szBackSlash); lstrcatW(package_path, source); @@ -1078,7 +1080,7 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, memset(&si,0,sizeof(STARTUPINFOW)); memset(&info,0,sizeof(PROCESS_INFORMATION)); - prop = msi_dup_property( package, source ); + prop = msi_dup_property( package->db, source ); if (!prop) return ERROR_SUCCESS; @@ -1380,7 +1382,7 @@ static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source, TRACE("%s %s\n", debugstr_w(source), debugstr_w(target)); - prop = msi_dup_property(package,source); + prop = msi_dup_property( package->db, source ); if (!prop) return ERROR_SUCCESS; @@ -1415,7 +1417,7 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package) EnterCriticalSection( &msi_custom_action_cs ); handle_count = list_count( &msi_pending_custom_actions ); - wait_handles = HeapAlloc( GetProcessHeap(), 0, handle_count * sizeof(HANDLE) ); + wait_handles = msi_alloc( handle_count * sizeof(HANDLE) ); handle_count = 0; LIST_FOR_EACH_ENTRY_SAFE( info, cursor, &msi_pending_custom_actions, msi_custom_action_info, entry ) @@ -1435,7 +1437,7 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package) CloseHandle( wait_handles[i] ); } - HeapFree( GetProcessHeap(), 0, wait_handles ); + msi_free( wait_handles ); } typedef struct _msi_custom_remote_impl { diff --git a/dll/win32/msi/database.c b/dll/win32/msi/database.c index cfa11e97ed5..3e577926340 100644 --- a/dll/win32/msi/database.c +++ b/dll/win32/msi/database.c @@ -164,64 +164,6 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm ) return SUCCEEDED(r) ? ERROR_SUCCESS : ERROR_FUNCTION_FAILED; } -UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname, - USHORT **pdata, UINT *psz ) -{ - HRESULT r; - UINT ret = ERROR_FUNCTION_FAILED; - VOID *data; - ULONG sz, count; - IStream *stm = NULL; - STATSTG stat; - LPWSTR encname; - - encname = encode_streamname( FALSE, stname ); - r = db_get_raw_stream( db, encname, &stm ); - msi_free( encname ); - - if( r != ERROR_SUCCESS) - return ret; - - r = IStream_Stat(stm, &stat, STATFLAG_NONAME ); - if( FAILED( r ) ) - { - WARN("open stream failed r = %08x!\n", r); - goto end; - } - - if( stat.cbSize.QuadPart >> 32 ) - { - WARN("Too big!\n"); - goto end; - } - - sz = stat.cbSize.QuadPart; - data = msi_alloc( sz ); - if( !data ) - { - WARN("couldn't allocate memory r=%08x!\n", r); - ret = ERROR_NOT_ENOUGH_MEMORY; - goto end; - } - - r = IStream_Read(stm, data, sz, &count ); - if( FAILED( r ) || ( count != sz ) ) - { - msi_free( data ); - WARN("read stream failed r = %08x!\n", r); - goto end; - } - - *pdata = data; - *psz = sz; - ret = ERROR_SUCCESS; - -end: - IStream_Release( stm ); - - return ret; -} - static void free_transforms( MSIDATABASE *db ) { while( !list_empty( &db->transforms ) ) @@ -234,6 +176,37 @@ static void free_transforms( MSIDATABASE *db ) } } +void db_destroy_stream( MSIDATABASE *db, LPCWSTR stname ) +{ + MSISTREAM *stream, *stream2; + + LIST_FOR_EACH_ENTRY_SAFE( stream, stream2, &db->streams, MSISTREAM, entry ) + { + HRESULT r; + STATSTG stat; + + r = IStream_Stat( stream->stm, &stat, 0 ); + if (FAILED(r)) + { + WARN("failed to stat stream r = %08x\n", r); + continue; + } + + if (!strcmpW( stname, stat.pwcsName )) + { + TRACE("destroying %s\n", debugstr_w(stname)); + + list_remove( &stream->entry ); + IStream_Release( stream->stm ); + msi_free( stream ); + IStorage_DestroyElement( db->storage, stname ); + CoTaskMemFree( stat.pwcsName ); + break; + } + CoTaskMemFree( stat.pwcsName ); + } +} + static void free_streams( MSIDATABASE *db ) { while( !list_empty( &db->streams ) ) @@ -289,7 +262,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) UINT ret = ERROR_FUNCTION_FAILED; LPCWSTR szMode, save_path; STATSTG stat; - BOOL created = FALSE; + BOOL created = FALSE, patch = FALSE; WCHAR path[MAX_PATH]; static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 }; @@ -304,6 +277,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) { TRACE("Database is a patch\n"); szPersist -= MSIDBOPEN_PATCHFILE; + patch = TRUE; } save_path = szDBPath; @@ -331,7 +305,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg); if( r == ERROR_SUCCESS ) { - IStorage_SetClass( stg, &CLSID_MsiDatabase ); + IStorage_SetClass( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase ); /* create the _Tables stream */ r = write_stream_data(stg, szTables, NULL, 0, TRUE); if (SUCCEEDED(r)) @@ -379,6 +353,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) goto end; } + if ( patch && !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) ) + { + ERR("storage GUID is not the MSI patch GUID %s\n", + debugstr_guid(&stat.clsid) ); + ret = ERROR_OPEN_FAILED; + goto end; + } + db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE), MSI_CloseDatabase ); if( !db ) diff --git a/dll/win32/msi/dialog.c b/dll/win32/msi/dialog.c index ac2e95af91f..2a00aa7cdeb 100644 --- a/dll/win32/msi/dialog.c +++ b/dll/win32/msi/dialog.c @@ -171,6 +171,8 @@ static MSIFEATURE *msi_seltree_get_selected_feature( msi_control *control ); static DWORD uiThreadId; static HWND hMsiHiddenWindow; +static LPWSTR msi_get_window_text( HWND hwnd ); + static INT msi_dialog_scale_unit( msi_dialog *dialog, INT val ) { return MulDiv( val, dialog->scale, 12 ); @@ -234,7 +236,7 @@ static LPWSTR msi_dialog_dup_property( msi_dialog *dialog, LPCWSTR property, BOO return NULL; if (indirect) - prop = msi_dup_property( dialog->package, property ); + prop = msi_dup_property( dialog->package->db, property ); if (!prop) prop = strdupW( property ); @@ -581,6 +583,13 @@ static void msi_dialog_update_controls( msi_dialog *dialog, LPCWSTR property ) } } +static void msi_dialog_set_property( MSIPACKAGE *package, LPCWSTR property, LPCWSTR value ) +{ + UINT r = msi_set_property( package->db, property, value ); + if (r == ERROR_SUCCESS && !strcmpW( property, cszSourceDir )) + msi_reset_folders( package, TRUE ); +} + /* called from the Control Event subscription code */ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, LPCWSTR attribute, MSIRECORD *rec ) @@ -634,14 +643,14 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, else if ( !lstrcmpW(attribute, szProperty) ) { MSIFEATURE *feature = msi_seltree_get_selected_feature( ctrl ); - MSI_SetPropertyW( dialog->package, ctrl->property, feature->Directory ); + msi_dialog_set_property( dialog->package, ctrl->property, feature->Directory ); } else if ( !lstrcmpW(attribute, szSelectionPath) ) { LPWSTR prop = msi_dialog_dup_property( dialog, ctrl->property, TRUE ); LPWSTR path; if (!prop) return; - path = msi_dup_property( dialog->package, prop ); + path = msi_dup_property( dialog->package->db, prop ); SetWindowTextW( ctrl->hwnd, path ); msi_free(prop); msi_free(path); @@ -884,7 +893,7 @@ static LPWSTR msi_get_checkbox_value( msi_dialog *dialog, LPCWSTR prop ) if (ret) return ret; - ret = msi_dup_property( dialog->package, prop ); + ret = msi_dup_property( dialog->package->db, prop ); if( ret && !ret[0] ) { msi_free( ret ); @@ -1222,10 +1231,167 @@ static UINT msi_dialog_icon_control( msi_dialog *dialog, MSIRECORD *rec ) return ERROR_SUCCESS; } +/******************** Combo Box ***************************************/ + +struct msi_combobox_info +{ + msi_dialog *dialog; + HWND hwnd; + WNDPROC oldproc; + DWORD num_items; + DWORD addpos_items; + LPWSTR *items; +}; + +static LRESULT WINAPI MSIComboBox_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + struct msi_combobox_info *info; + LRESULT r; + DWORD j; + + TRACE("%p %04x %08lx %08lx\n", hWnd, msg, wParam, lParam); + + info = GetPropW( hWnd, szButtonData ); + if (!info) + return 0; + + r = CallWindowProcW( info->oldproc, hWnd, msg, wParam, lParam ); + + switch (msg) + { + case WM_NCDESTROY: + for (j = 0; j < info->num_items; j++) + msi_free( info->items[j] ); + msi_free( info->items ); + msi_free( info ); + RemovePropW( hWnd, szButtonData ); + break; + } + + return r; +} + +static UINT msi_combobox_add_item( MSIRECORD *rec, LPVOID param ) +{ + struct msi_combobox_info *info = param; + LPCWSTR value, text; + int pos; + + value = MSI_RecordGetString( rec, 3 ); + text = MSI_RecordGetString( rec, 4 ); + + info->items[info->addpos_items] = strdupW( value ); + + pos = SendMessageW( info->hwnd, CB_ADDSTRING, 0, (LPARAM)text ); + SendMessageW( info->hwnd, CB_SETITEMDATA, pos, (LPARAM)info->items[info->addpos_items] ); + info->addpos_items++; + + return ERROR_SUCCESS; +} + +static UINT msi_combobox_add_items( struct msi_combobox_info *info, LPCWSTR property ) +{ + UINT r; + MSIQUERY *view = NULL; + DWORD count; + + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ', + 'F','R','O','M',' ','`','C','o','m','b','o','B','o','x','`',' ', + 'W','H','E','R','E',' ', + '`','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',' ', + 'O','R','D','E','R',' ','B','Y',' ','`','O','r','d','e','r','`',0 + }; + + r = MSI_OpenQuery( info->dialog->package->db, &view, query, property ); + if (r != ERROR_SUCCESS) + return r; + + /* just get the number of records */ + count = 0; + r = MSI_IterateRecords( view, &count, NULL, NULL ); + + info->num_items = count; + info->items = msi_alloc( sizeof(*info->items) * count ); + + r = MSI_IterateRecords( view, NULL, msi_combobox_add_item, info ); + msiobj_release( &view->hdr ); + + return r; +} + +static UINT msi_dialog_combobox_handler( msi_dialog *dialog, + msi_control *control, WPARAM param ) +{ + struct msi_combobox_info *info; + int index; + LPWSTR value; + + if (HIWORD(param) != CBN_SELCHANGE && HIWORD(param) != CBN_EDITCHANGE) + return ERROR_SUCCESS; + + info = GetPropW( control->hwnd, szButtonData ); + index = SendMessageW( control->hwnd, CB_GETCURSEL, 0, 0 ); + if (index == CB_ERR) + value = msi_get_window_text( control->hwnd ); + else + value = (LPWSTR) SendMessageW( control->hwnd, CB_GETITEMDATA, index, 0 ); + + msi_dialog_set_property( info->dialog->package, control->property, value ); + msi_dialog_evaluate_control_conditions( info->dialog ); + + if (index == CB_ERR) + msi_free( value ); + + return ERROR_SUCCESS; +} + +static void msi_dialog_combobox_update( msi_dialog *dialog, + msi_control *control ) +{ + struct msi_combobox_info *info; + LPWSTR value, tmp; + DWORD j; + + info = GetPropW( control->hwnd, szButtonData ); + + value = msi_dup_property( dialog->package->db, control->property ); + if (!value) + { + SendMessageW( control->hwnd, CB_SETCURSEL, -1, 0 ); + return; + } + + for (j = 0; j < info->num_items; j++) + { + tmp = (LPWSTR) SendMessageW( control->hwnd, CB_GETITEMDATA, j, 0 ); + if (!lstrcmpW( value, tmp )) + break; + } + + if (j < info->num_items) + { + SendMessageW( control->hwnd, CB_SETCURSEL, j, 0 ); + } + else + { + SendMessageW( control->hwnd, CB_SETCURSEL, -1, 0 ); + SetWindowTextW( control->hwnd, value ); + } + + msi_free(value); +} + static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec ) { - static const WCHAR szCombo[] = { 'C','O','M','B','O','B','O','X',0 }; + struct msi_combobox_info *info; + msi_control *control; DWORD attributes, style; + LPCWSTR prop; + + info = msi_alloc( sizeof *info ); + if (!info) + return ERROR_FUNCTION_FAILED; style = CBS_AUTOHSCROLL | WS_TABSTOP | WS_GROUP | WS_CHILD; attributes = MSI_RecordGetInteger( rec, 8 ); @@ -1236,7 +1402,33 @@ static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec ) else style |= CBS_DROPDOWN; - msi_dialog_add_control( dialog, rec, szCombo, style ); + control = msi_dialog_add_control( dialog, rec, WC_COMBOBOXW, style ); + if (!control) + { + msi_free( info ); + return ERROR_FUNCTION_FAILED; + } + + control->handler = msi_dialog_combobox_handler; + control->update = msi_dialog_combobox_update; + + prop = MSI_RecordGetString( rec, 9 ); + control->property = msi_dialog_dup_property( dialog, prop, FALSE ); + + /* subclass */ + info->dialog = dialog; + info->hwnd = control->hwnd; + info->items = NULL; + info->addpos_items = 0; + info->oldproc = (WNDPROC)SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC, + (LONG_PTR)MSIComboBox_WndProc ); + SetPropW( control->hwnd, szButtonData, info ); + + if (control->property) + msi_combobox_add_items( info, control->property ); + + msi_dialog_combobox_update( dialog, control ); + return ERROR_SUCCESS; } @@ -1276,7 +1468,7 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec ) if( prop ) control->property = strdupW( prop ); - val = msi_dup_property( dialog->package, control->property ); + val = msi_dup_property( dialog->package->db, control->property ); SetWindowTextW( control->hwnd, val ); msi_free( val ); return ERROR_SUCCESS; @@ -1352,10 +1544,9 @@ static void msi_mask_control_change( struct msi_maskedit_info *info ) if( i == info->num_groups ) { - TRACE("Set property %s to %s\n", - debugstr_w(info->prop), debugstr_w(val) ); + TRACE("Set property %s to %s\n", debugstr_w(info->prop), debugstr_w(val)); CharUpperBuffW( val, info->num_chars ); - MSI_SetPropertyW( info->dialog->package, info->prop, val ); + msi_dialog_set_property( info->dialog->package, info->prop, val ); msi_dialog_evaluate_control_conditions( info->dialog ); } msi_free( val ); @@ -1587,7 +1778,7 @@ static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec ) if( prop ) { - val = msi_dup_property( dialog->package, prop ); + val = msi_dup_property( dialog->package->db, prop ); if( val ) { msi_maskedit_set_text( info, val ); @@ -1705,7 +1896,7 @@ static BOOL msi_dialog_onkillfocus( msi_dialog *dialog, msi_control *control ) else { valid = TRUE; - MSI_SetPropertyW( dialog->package, prop, buf ); + msi_dialog_set_property( dialog->package, prop, buf ); } msi_dialog_update_pathedit( dialog, control ); @@ -1855,7 +2046,7 @@ static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec ) group.dialog = dialog; group.parent = control; group.attributes = MSI_RecordGetInteger( rec, 8 ); - group.propval = msi_dup_property( dialog->package, control->property ); + group.propval = msi_dup_property( dialog->package->db, control->property ); r = MSI_IterateRecords( view, 0, msi_dialog_create_radiobutton, &group ); msiobj_release( &view->hdr ); @@ -2357,8 +2548,7 @@ static UINT msi_dialog_listbox_handler( msi_dialog *dialog, index = SendMessageW( control->hwnd, LB_GETCURSEL, 0, 0 ); value = (LPCWSTR) SendMessageW( control->hwnd, LB_GETITEMDATA, index, 0 ); - MSI_SetPropertyW( info->dialog->package, - control->property, value ); + msi_dialog_set_property( info->dialog->package, control->property, value ); msi_dialog_evaluate_control_conditions( info->dialog ); return ERROR_SUCCESS; @@ -2521,7 +2711,7 @@ UINT msi_dialog_directorylist_up( msi_dialog *dialog ) if (ptr != path) *(ptr - 1) = '\0'; PathAddBackslashW( path ); - MSI_SetPropertyW( dialog->package, prop, path ); + msi_dialog_set_property( dialog->package, prop, path ); msi_dialog_update_directory_list( dialog, NULL ); msi_dialog_update_directory_combo( dialog, NULL ); @@ -2567,7 +2757,7 @@ static UINT msi_dialog_dirlist_handler( msi_dialog *dialog, lstrcatW( new_path, text ); lstrcatW( new_path, szBackSlash ); - MSI_SetPropertyW( dialog->package, prop, new_path ); + msi_dialog_set_property( dialog->package, prop, new_path ); msi_dialog_update_directory_list( dialog, NULL ); msi_dialog_update_directory_combo( dialog, NULL ); @@ -2810,7 +3000,7 @@ static UINT msi_dialog_volsel_handler( msi_dialog *dialog, indirect = control->attributes & msidbControlAttributesIndirect; prop = msi_dialog_dup_property( dialog, control->property, indirect ); - MSI_SetPropertyW( dialog->package, prop, text ); + msi_dialog_set_property( dialog->package, prop, text ); msi_free( prop ); return ERROR_SUCCESS; @@ -3078,8 +3268,8 @@ static void msi_dialog_adjust_dialog_pos( msi_dialog *dialog, MSIRECORD *rec, LP sz.cx = msi_dialog_scale_unit( dialog, sz.cx ); sz.cy = msi_dialog_scale_unit( dialog, sz.cy ); - xres = msi_get_property_int( dialog->package, szScreenX, 0 ); - yres = msi_get_property_int( dialog->package, szScreenY, 0 ); + xres = msi_get_property_int( dialog->package->db, szScreenX, 0 ); + yres = msi_get_property_int( dialog->package->db, szScreenY, 0 ); center.x = MulDiv( center.x, xres, 100 ); center.y = MulDiv( center.y, yres, 100 ); @@ -3172,7 +3362,7 @@ static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs ) dialog->attributes = MSI_RecordGetInteger( rec, 6 ); - dialog->default_font = msi_dup_property( dialog->package, df ); + dialog->default_font = msi_dup_property( dialog->package->db, df ); if (!dialog->default_font) { dialog->default_font = strdupW(dfv); @@ -3213,7 +3403,7 @@ static UINT msi_dialog_send_event( msi_dialog *dialog, LPCWSTR event, LPCWSTR ar return ERROR_SUCCESS; } -static UINT msi_dialog_set_property( msi_dialog *dialog, LPCWSTR event, LPCWSTR arg ) +static UINT msi_dialog_set_property_event( msi_dialog *dialog, LPCWSTR event, LPCWSTR arg ) { static const WCHAR szNullArg[] = { '{','}',0 }; LPWSTR p, prop, arg_fmt = NULL; @@ -3228,7 +3418,7 @@ static UINT msi_dialog_set_property( msi_dialog *dialog, LPCWSTR event, LPCWSTR *p = 0; if( strcmpW( szNullArg, arg ) ) deformat_string( dialog->package, arg, &arg_fmt ); - MSI_SetPropertyW( dialog->package, prop, arg_fmt ); + msi_dialog_set_property( dialog->package, prop, arg_fmt ); msi_dialog_update_controls( dialog, prop ); msi_free( arg_fmt ); } @@ -3251,7 +3441,7 @@ static UINT msi_dialog_control_event( MSIRECORD *rec, LPVOID param ) event = MSI_RecordGetString( rec, 3 ); arg = MSI_RecordGetString( rec, 4 ); if( event[0] == '[' ) - msi_dialog_set_property( dialog, event, arg ); + msi_dialog_set_property_event( dialog, event, arg ); else msi_dialog_send_event( dialog, event, arg ); } @@ -3366,7 +3556,7 @@ static UINT msi_dialog_get_checkbox_state( msi_dialog *dialog, WCHAR state[2] = { 0 }; DWORD sz = 2; - MSI_GetPropertyW( dialog->package, control->property, state, &sz ); + msi_get_property( dialog->package->db, control->property, state, &sz ); return state[0] ? 1 : 0; } @@ -3379,7 +3569,7 @@ static void msi_dialog_set_checkbox_state( msi_dialog *dialog, /* if uncheck then the property is set to NULL */ if (!state) { - MSI_SetPropertyW( dialog->package, control->property, NULL ); + msi_dialog_set_property( dialog->package, control->property, NULL ); return; } @@ -3389,7 +3579,7 @@ static void msi_dialog_set_checkbox_state( msi_dialog *dialog, else val = szState; - MSI_SetPropertyW( dialog->package, control->property, val ); + msi_dialog_set_property( dialog->package, control->property, val ); } static void msi_dialog_checkbox_sync_state( msi_dialog *dialog, @@ -3433,8 +3623,7 @@ static UINT msi_dialog_edit_handler( msi_dialog *dialog, debugstr_w(control->property)); buf = msi_get_window_text( control->hwnd ); - MSI_SetPropertyW( dialog->package, control->property, buf ); - + msi_dialog_set_property( dialog->package, control->property, buf ); msi_free( buf ); return ERROR_SUCCESS; @@ -3449,7 +3638,7 @@ static UINT msi_dialog_radiogroup_handler( msi_dialog *dialog, TRACE("clicked radio button %s, set %s\n", debugstr_w(control->name), debugstr_w(control->property)); - MSI_SetPropertyW( dialog->package, control->property, control->name ); + msi_dialog_set_property( dialog->package, control->property, control->name ); return msi_dialog_button_handler( dialog, control, param ); } @@ -3835,7 +4024,7 @@ static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event, if ( !lstrcmpW( argument, error_abort ) || !lstrcmpW( argument, error_cancel ) || !lstrcmpW( argument, error_no ) ) { - MSI_SetPropertyW( package, result_prop, error_abort ); + msi_set_property( package->db, result_prop, error_abort ); } ControlEvent_CleanupSubscriptions(package); @@ -3878,12 +4067,12 @@ UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR er 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0 }; - if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE ) + if ( (msi_get_property_int( package->db, szUILevel, 0 ) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE ) return ERROR_SUCCESS; if ( !error_dialog ) { - LPWSTR product_name = msi_dup_property( package, pn_prop ); + LPWSTR product_name = msi_dup_property( package->db, pn_prop ); WCHAR title[MAX_PATH]; sprintfW( title, title_fmt, product_name ); @@ -3911,7 +4100,7 @@ UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR er if ( r != ERROR_SUCCESS ) goto done; - r = MSI_GetPropertyW( package, result_prop, result, &size ); + r = msi_get_property( package->db, result_prop, result, &size ); if ( r != ERROR_SUCCESS) r = ERROR_SUCCESS; diff --git a/dll/win32/msi/events.c b/dll/win32/msi/events.c index e8f22975594..4ed395bbc59 100644 --- a/dll/win32/msi/events.c +++ b/dll/win32/msi/events.c @@ -226,7 +226,7 @@ static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument, static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument, msi_dialog* dialog) { - LPWSTR path = msi_dup_property( package, argument ); + LPWSTR path = msi_dup_property( package->db, argument ); MSIRECORD *rec = MSI_CreateRecord( 1 ); UINT r; @@ -380,7 +380,13 @@ static UINT ControlEvent_DirectoryListUp(MSIPACKAGE *package, LPCWSTR argument, static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog) { - return MSI_SetPropertyW( package, szReinstallMode, argument ); + return msi_set_property( package->db, szReinstallMode, argument ); +} + +static UINT ControlEvent_Reinstall( MSIPACKAGE *package, LPCWSTR argument, + msi_dialog *dialog ) +{ + return msi_set_property( package->db, szReinstall, argument ); } static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument, @@ -389,13 +395,13 @@ static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument LPWSTR key, template; UINT ret = ERROR_SUCCESS; - template = msi_dup_property( package, szPIDTemplate ); - key = msi_dup_property( package, szPIDKEY ); + template = msi_dup_property( package->db, szPIDTemplate ); + key = msi_dup_property( package->db, szPIDKEY ); if (key && template) { FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) ); - ret = MSI_SetPropertyW( package, szProductID, key ); + ret = msi_set_property( package->db, szProductID, key ); } msi_free( template ); msi_free( key ); @@ -417,6 +423,7 @@ static const struct _events Events[] = { { "DirectoryListUp",ControlEvent_DirectoryListUp }, { "SelectionBrowse",ControlEvent_SpawnDialog }, { "ReinstallMode",ControlEvent_ReinstallMode }, + { "Reinstall",ControlEvent_Reinstall }, { "ValidateProductID",ControlEvent_ValidateProductID }, { NULL,NULL }, }; diff --git a/dll/win32/msi/files.c b/dll/win32/msi/files.c index 40501636af2..052a1588e2e 100644 --- a/dll/win32/msi/files.c +++ b/dll/win32/msi/files.c @@ -98,6 +98,8 @@ static void schedule_install_files(MSIPACKAGE *package) ui_progress(package,2,file->FileSize,0,0); file->state = msifs_skipped; } + else + file->Component->Action = INSTALLSTATE_LOCAL; } } @@ -119,8 +121,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) { UINT gle; - TRACE("Copying %s to %s\n", debugstr_w(source), - debugstr_w(file->TargetPath)); + TRACE("Copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath)); gle = copy_file(file, source); if (gle == ERROR_SUCCESS) @@ -147,7 +148,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) GetTempFileNameW(szBackSlash, szMsi, 0, tmpfileW); len = strlenW(file->TargetPath) + strlenW(tmpfileW) + 1; - if (!(pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) + if (!(pathW = msi_alloc(len * sizeof(WCHAR)))) return ERROR_OUTOFMEMORY; strcpyW(pathW, file->TargetPath); @@ -167,32 +168,17 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) gle = GetLastError(); WARN("failed to schedule rename operation: %d)\n", gle); } - HeapFree(GetProcessHeap(), 0, pathW); + msi_free(pathW); } return gle; } -static BOOL check_dest_hash_matches(MSIFILE *file) -{ - MSIFILEHASHINFO hash; - UINT r; - - if (!file->hash.dwFileHashInfoSize) - return FALSE; - - hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO); - r = MsiGetFileHashW(file->TargetPath, 0, &hash); - if (r != ERROR_SUCCESS) - return FALSE; - - return !memcmp(&hash, &file->hash, sizeof(MSIFILEHASHINFO)); -} - static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, LPWSTR *path, DWORD *attrs, PVOID user) { static MSIFILE *f = NULL; + MSIMEDIAINFO *mi = user; if (action == MSICABEXTRACT_BEGINEXTRACT) { @@ -203,11 +189,8 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, return FALSE; } - if (f->state != msifs_missing && f->state != msifs_overwrite) - { - TRACE("Skipping extraction of %s\n", debugstr_w(file)); + if (f->disk_id != mi->disk_id || (f->state != msifs_missing && f->state != msifs_overwrite)) return FALSE; - } msi_file_update_ui(package, f, szInstallFiles); @@ -256,19 +239,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) if (file->state != msifs_missing && !mi->is_continuous && file->state != msifs_overwrite) continue; - if (check_dest_hash_matches(file)) - { - TRACE("File hashes match, not overwriting\n"); - continue; - } - - if (MsiGetFileVersionW(file->TargetPath, NULL, NULL, NULL, NULL) == ERROR_SUCCESS && - msi_compare_file_version(file) >= 0) - { - TRACE("Destination file version greater, not overwriting\n"); - continue; - } - if (file->Sequence > mi->last_sequence || mi->is_continuous || (file->IsCompressed && !mi->is_extracted)) { @@ -277,20 +247,20 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) rc = ready_media(package, file, mi); if (rc != ERROR_SUCCESS) { - ERR("Failed to ready media\n"); + ERR("Failed to ready media for %s\n", debugstr_w(file->File)); break; } data.mi = mi; data.package = package; data.cb = installfiles_cb; - data.user = NULL; + data.user = mi; if (file->IsCompressed && !msi_cabextract(package, mi, &data)) { ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet)); - rc = ERROR_FUNCTION_FAILED; + rc = ERROR_INSTALL_FAILURE; break; } } @@ -317,8 +287,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) } else if (file->state != msifs_installed) { - ERR("compressed file wasn't extracted (%s)\n", - debugstr_w(file->TargetPath)); + ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->TargetPath)); rc = ERROR_INSTALL_FAILURE; break; } @@ -555,11 +524,11 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) sourcename = MSI_RecordGetString(rec, 3); options = MSI_RecordGetInteger(rec, 7); - sourcedir = msi_dup_property(package, MSI_RecordGetString(rec, 5)); + sourcedir = msi_dup_property(package->db, MSI_RecordGetString(rec, 5)); if (!sourcedir) goto done; - destdir = msi_dup_property(package, MSI_RecordGetString(rec, 6)); + destdir = msi_dup_property(package->db, MSI_RecordGetString(rec, 6)); if (!destdir) goto done; @@ -704,7 +673,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const if (!dst_path) { /* try a property */ - dst_path = msi_dup_property( package, dst_key ); + dst_path = msi_dup_property( package->db, dst_key ); if (!dst_path) { FIXME("Unable to get destination folder, try AppSearch properties\n"); @@ -917,7 +886,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) UINT install_mode; LPWSTR dir = NULL, path = NULL; DWORD size; - UINT r; + UINT ret = ERROR_SUCCESS; component = MSI_RecordGetString(row, 2); filename = MSI_RecordGetString(row, 3); @@ -938,7 +907,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; } - dir = msi_dup_property(package, dirprop); + dir = msi_dup_property(package->db, dirprop); if (!dir) return ERROR_OUTOFMEMORY; @@ -947,7 +916,7 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) path = msi_alloc(size * sizeof(WCHAR)); if (!path) { - r = ERROR_OUTOFMEMORY; + ret = ERROR_OUTOFMEMORY; goto done; } @@ -975,7 +944,7 @@ done: msi_free(path); msi_free(dir); - return ERROR_SUCCESS; + return ret; } UINT ACTION_RemoveFiles( MSIPACKAGE *package ) diff --git a/dll/win32/msi/font.c b/dll/win32/msi/font.c index 1b2c3c729dd..1d99a4c0d3a 100644 --- a/dll/win32/msi/font.c +++ b/dll/win32/msi/font.c @@ -64,11 +64,6 @@ typedef struct _tagTT_NAME_RECORD { #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) -static const WCHAR szRegisterFonts[] = - {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; -static const WCHAR szUnregisterFonts[] = - {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0}; - static const WCHAR regfont1[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', diff --git a/dll/win32/msi/format.c b/dll/win32/msi/format.c index f59024abf86..c4ff30f4111 100644 --- a/dll/win32/msi/format.c +++ b/dll/win32/msi/format.c @@ -175,7 +175,7 @@ static LPWSTR deformat_property(FORMAT *format, FORMSTR *str) val = msi_alloc((str->len + 1) * sizeof(WCHAR)); lstrcpynW(val, get_formstr_data(format, str), str->len + 1); - ret = msi_dup_property(format->package, val); + ret = msi_dup_property(format->package->db, val); msi_free(val); return ret; @@ -805,12 +805,12 @@ static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, format.deformatted = *data; format.len = *len; - stack = create_stack(); - temp = create_stack(); - if (!verify_format(*data)) return ERROR_SUCCESS; + stack = create_stack(); + temp = create_stack(); + while ((type = format_lex(&format, &str)) != FORMAT_NULL) { if (type == FORMAT_LBRACK || type == FORMAT_LBRACE || diff --git a/dll/win32/msi/helpers.c b/dll/win32/msi/helpers.c index c45ba236d50..54d21994a6d 100644 --- a/dll/win32/msi/helpers.c +++ b/dll/win32/msi/helpers.c @@ -47,7 +47,7 @@ LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name ) static const WCHAR szFolder[] = {'A','p','p','D','a','t','a','F','o','l','d','e','r',0}; - SystemFolder = msi_dup_property( package, szFolder ); + SystemFolder = msi_dup_property( package->db, szFolder ); dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode); @@ -160,11 +160,11 @@ static LPWSTR get_source_root( MSIPACKAGE *package ) { LPWSTR path, p; - path = msi_dup_property( package, cszSourceDir ); + path = msi_dup_property( package->db, cszSourceDir ); if (path) return path; - path = msi_dup_property( package, cszDatabase ); + path = msi_dup_property( package->db, cszDatabase ); if (path) { p = strrchrW(path,'\\'); @@ -265,19 +265,19 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, if (!f->ResolvedTarget && !f->Property) { LPWSTR check_path; - check_path = msi_dup_property( package, cszTargetDir ); + check_path = msi_dup_property( package->db, cszTargetDir ); if (!check_path) { - check_path = msi_dup_property( package, cszRootDrive ); + check_path = msi_dup_property( package->db, cszRootDrive ); if (set_prop) - MSI_SetPropertyW(package,cszTargetDir,check_path); + msi_set_property( package->db, cszTargetDir, check_path ); } /* correct misbuilt target dir */ path = build_directory_name(2, check_path, NULL); clean_spaces_from_path( path ); if (strcmpiW(path,check_path)!=0) - MSI_SetPropertyW(package,cszTargetDir,path); + msi_set_property( package->db, cszTargetDir, path ); msi_free(check_path); f->ResolvedTarget = path; @@ -310,11 +310,11 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, TRACE(" internally set to %s\n",debugstr_w(path)); if (set_prop) - MSI_SetPropertyW( package, name, path ); + msi_set_property( package->db, name, path ); return path; } - if (!source && load_prop && (path = msi_dup_property( package, name ))) + if (!source && load_prop && (path = msi_dup_property( package->db, name ))) { f->ResolvedTarget = strdupW( path ); TRACE(" property set to %s\n", debugstr_w(path)); @@ -338,7 +338,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, f->ResolvedTarget = strdupW( path ); TRACE("target -> %s\n", debugstr_w(path)); if (set_prop) - MSI_SetPropertyW(package,name,path); + msi_set_property( package->db, name, path ); } else { diff --git a/dll/win32/msi/install.c b/dll/win32/msi/install.c index c23075d61d3..fda49b90d8d 100644 --- a/dll/win32/msi/install.c +++ b/dll/win32/msi/install.c @@ -709,7 +709,7 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) break; case MSIRUNMODE_MAINTENANCE: - r = msi_get_property_int( package, szInstalled, 0 ) != 0; + r = msi_get_property_int( package->db, szInstalled, 0 ) != 0; break; case MSIRUNMODE_REBOOTATEND: @@ -721,6 +721,7 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) r = TRUE; } + msiobj_release( &package->hdr ); return r; } @@ -774,6 +775,7 @@ UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState) r = ERROR_ACCESS_DENIED; } + msiobj_release( &package->hdr ); return r; } @@ -1262,7 +1264,7 @@ LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall) return 0; } - langid = msi_get_property_int( package, szProductLanguage, 0 ); + langid = msi_get_property_int( package->db, szProductLanguage, 0 ); msiobj_release( &package->hdr ); return langid; } @@ -1284,7 +1286,7 @@ UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) return MSI_SetFeatureStates( package ); sprintfW( level, fmt, iInstallLevel ); - r = MSI_SetPropertyW( package, szInstallLevel, level ); + r = msi_set_property( package->db, szInstallLevel, level ); if ( r == ERROR_SUCCESS ) r = MSI_SetFeatureStates( package ); diff --git a/dll/win32/msi/media.c b/dll/win32/msi/media.c index 0a6c4314fbc..49bc199cc36 100644 --- a/dll/win32/msi/media.c +++ b/dll/win32/msi/media.c @@ -20,6 +20,8 @@ #include +#define COBJMACROS + #include "windef.h" #include "winerror.h" #include "wine/debug.h" @@ -28,6 +30,7 @@ #include "winuser.h" #include "winreg.h" #include "shlwapi.h" +#include "objidl.h" #include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -76,13 +79,13 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0}; - if ((msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == + if ((msi_get_property_int(package->db, szUILevel, 0) & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE && !gUIHandlerA && !gUIHandlerW && !gUIHandlerRecord) return ERROR_SUCCESS; error = generate_error_string(package, 1302, 1, mi->disk_prompt); - error_dialog = msi_dup_property(package, error_prop); - source_dir = msi_dup_property(package, cszSourceDir); + error_dialog = msi_dup_property(package->db, error_prop); + source_dir = msi_dup_property(package->db, cszSourceDir); while (r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir)) { @@ -114,49 +117,6 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) return r; } -static UINT writeout_cabinet_stream(MSIPACKAGE *package, LPCWSTR stream, - WCHAR* source) -{ - UINT rc; - USHORT* data; - UINT size; - DWORD write; - HANDLE hfile; - WCHAR tmp[MAX_PATH]; - - static const WCHAR cszTempFolder[]= { - 'T','e','m','p','F','o','l','d','e','r',0}; - - rc = read_raw_stream_data(package->db, stream, &data, &size); - if (rc != ERROR_SUCCESS) - return rc; - - write = MAX_PATH; - if (MSI_GetPropertyW(package, cszTempFolder, tmp, &write)) - GetTempPathW(MAX_PATH, tmp); - - GetTempFileNameW(tmp, stream, 0, source); - - track_tempfile(package, source); - hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - - if (hfile == INVALID_HANDLE_VALUE) - { - ERR("Unable to create file %s\n", debugstr_w(source)); - rc = ERROR_FUNCTION_FAILED; - goto end; - } - - WriteFile(hfile, data, size, &write, NULL); - CloseHandle(hfile); - TRACE("wrote %i bytes to %s\n", write, debugstr_w(source)); - -end: - msi_free(data); - return rc; -} - static void * CDECL cabinet_alloc(ULONG cb) { return msi_alloc(cb); @@ -238,10 +198,72 @@ static LONG CDECL cabinet_seek(INT_PTR hf, LONG dist, int seektype) return SetFilePointer(handle, dist, NULL, seektype); } +struct cab_stream +{ + MSIDATABASE *db; + WCHAR *name; +}; + +static struct cab_stream cab_stream; + +static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode ) +{ + UINT r; + IStream *stm; + + if (oflag) + WARN("ignoring open flags 0x%08x\n", oflag); + + r = db_get_raw_stream( cab_stream.db, cab_stream.name, &stm ); + if (r != ERROR_SUCCESS) + { + WARN("Failed to get cabinet stream %u\n", r); + return 0; + } + + return (INT_PTR)stm; +} + +static UINT CDECL cabinet_read_stream( INT_PTR hf, void *pv, UINT cb ) +{ + IStream *stm = (IStream *)hf; + DWORD read; + HRESULT hr; + + hr = IStream_Read( stm, pv, cb, &read ); + if (hr == S_OK || hr == S_FALSE) + return read; + + return 0; +} + +static int CDECL cabinet_close_stream( INT_PTR hf ) +{ + IStream *stm = (IStream *)hf; + IStream_Release( stm ); + return 0; +} + +static LONG CDECL cabinet_seek_stream( INT_PTR hf, LONG dist, int seektype ) +{ + IStream *stm = (IStream *)hf; + LARGE_INTEGER move; + ULARGE_INTEGER newpos; + HRESULT hr; + + move.QuadPart = dist; + hr = IStream_Seek( stm, move, seektype, &newpos ); + if (SUCCEEDED(hr)) + { + if (newpos.QuadPart <= MAXLONG) return newpos.QuadPart; + ERR("Too big!\n"); + } + return -1; +} + static UINT CDECL msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi) { MSIRECORD *row; - LPWSTR ptr; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', @@ -262,10 +284,7 @@ static UINT CDECL msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (!mi->first_volume) mi->first_volume = strdupW(mi->volume_label); - ptr = strrchrW(mi->source, '\\') + 1; - lstrcpyW(ptr, mi->cabinet); msiobj_release(&row->hdr); - return ERROR_SUCCESS; } @@ -277,12 +296,24 @@ static INT_PTR cabinet_partial_file(FDINOTIFICATIONTYPE fdint, return 0; } +static WCHAR *get_cabinet_filename(MSIMEDIAINFO *mi) +{ + int len; + WCHAR *ret; + + len = strlenW(mi->sourcedir) + strlenW(mi->cabinet) + 1; + if (!(ret = msi_alloc(len * sizeof(WCHAR)))) return NULL; + strcpyW(ret, mi->sourcedir); + strcatW(ret, mi->cabinet); + return ret; +} + static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { MSICABDATA *data = pfdin->pv; MSIMEDIAINFO *mi = data->mi; - LPWSTR cab = strdupAtoW(pfdin->psz1); + LPWSTR cabinet_file = NULL, cab = strdupAtoW(pfdin->psz1); INT_PTR res = -1; UINT rc; @@ -309,10 +340,13 @@ static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, goto done; } - TRACE("Searching for %s\n", debugstr_w(mi->source)); + if (!(cabinet_file = get_cabinet_filename(mi))) + goto done; + + TRACE("Searching for %s\n", debugstr_w(cabinet_file)); res = 0; - if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES) { if (msi_change_media(data->package, mi) != ERROR_SUCCESS) res = -1; @@ -320,6 +354,7 @@ static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, done: msi_free(cab); + msi_free(cabinet_file); return res; } @@ -376,7 +411,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, GetTempFileNameW(szBackSlash, szMsi, 0, tmpfileW); len = strlenW(path) + strlenW(tmpfileW) + 1; - if (!(tmppathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) + if (!(tmppathW = msi_alloc(len * sizeof(WCHAR)))) return ERROR_OUTOFMEMORY; strcpyW(tmppathW, path); @@ -394,7 +429,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, else WARN("failed to schedule rename operation %s (error %d)\n", debugstr_w(path), GetLastError()); - HeapFree(GetProcessHeap(), 0, tmppathW); + msi_free(tmppathW); } else WARN("failed to create %s (error %d)\n", debugstr_w(path), err); @@ -436,8 +471,6 @@ static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint, static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { - TRACE("(%d)\n", fdint); - switch (fdint) { case fdintPARTIAL_FILE: @@ -457,48 +490,58 @@ static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION } } -/*********************************************************************** - * msi_cabextract - * - * Extract files from a cab file. - */ -BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data) +static INT_PTR CDECL cabinet_notify_stream( FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin ) +{ + switch (fdint) + { + case fdintCOPY_FILE: + return cabinet_copy_file( fdint, pfdin ); + + case fdintCLOSE_FILE_INFO: + return cabinet_close_file_info( fdint, pfdin ); + + case fdintCABINET_INFO: + return 0; + + default: + ERR("Unexpected notification %d\n", fdint); + return 0; + } +} + +static BOOL extract_cabinet( MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data ) { LPSTR cabinet, cab_path = NULL; - LPWSTR ptr; HFDI hfdi; ERF erf; BOOL ret = FALSE; - TRACE("Extracting %s\n", debugstr_w(mi->source)); + TRACE("Extracting %s\n", debugstr_w(mi->cabinet)); - hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read, - cabinet_write, cabinet_close, cabinet_seek, 0, &erf); + hfdi = FDICreate( cabinet_alloc, cabinet_free, cabinet_open, cabinet_read, + cabinet_write, cabinet_close, cabinet_seek, 0, &erf ); if (!hfdi) { ERR("FDICreate failed\n"); return FALSE; } - ptr = strrchrW(mi->source, '\\') + 1; - cabinet = strdupWtoA(ptr); + cabinet = strdupWtoA( mi->cabinet ); if (!cabinet) goto done; - cab_path = strdupWtoA(mi->source); + cab_path = strdupWtoA( mi->sourcedir ); if (!cab_path) goto done; - cab_path[ptr - mi->source] = '\0'; - - ret = FDICopy(hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data); + ret = FDICopy( hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data ); if (!ret) ERR("FDICopy failed\n"); done: - FDIDestroy(hfdi); - msi_free(cabinet); - msi_free(cab_path); + FDIDestroy( hfdi ); + msi_free(cabinet ); + msi_free( cab_path ); if (ret) mi->is_extracted = TRUE; @@ -506,6 +549,56 @@ done: return ret; } +static BOOL extract_cabinet_stream( MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data ) +{ + static char filename[] = {'<','S','T','R','E','A','M','>',0}; + HFDI hfdi; + ERF erf; + BOOL ret = FALSE; + + TRACE("Extracting %s\n", debugstr_w(mi->cabinet)); + + hfdi = FDICreate( cabinet_alloc, cabinet_free, cabinet_open_stream, cabinet_read_stream, + cabinet_write, cabinet_close_stream, cabinet_seek_stream, 0, &erf ); + if (!hfdi) + { + ERR("FDICreate failed\n"); + return FALSE; + } + + cab_stream.db = package->db; + cab_stream.name = encode_streamname( FALSE, mi->cabinet + 1 ); + if (!cab_stream.name) + goto done; + + ret = FDICopy( hfdi, filename, NULL, 0, cabinet_notify_stream, NULL, data ); + if (!ret) + ERR("FDICopy failed\n"); + +done: + FDIDestroy( hfdi ); + msi_free( cab_stream.name ); + + if (ret) + mi->is_extracted = TRUE; + + return ret; +} + +/*********************************************************************** + * msi_cabextract + * + * Extract files from a cabinet file or stream. + */ +BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data) +{ + if (mi->cabinet[0] == '#') + { + return extract_cabinet_stream( package, mi, data ); + } + return extract_cabinet( package, mi, data ); +} + void msi_free_media_info(MSIMEDIAINFO *mi) { msi_free(mi->disk_prompt); @@ -532,7 +625,6 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO LPWSTR source_dir; LPWSTR source; DWORD options; - UINT r; static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', @@ -563,25 +655,10 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO if (!mi->first_volume) mi->first_volume = strdupW(mi->volume_label); - source_dir = msi_dup_property(package, cszSourceDir); - lstrcpyW(mi->source, source_dir); + source_dir = msi_dup_property(package->db, cszSourceDir); + lstrcpyW(mi->sourcedir, source_dir); mi->type = get_drive_type(source_dir); - if (file->IsCompressed && mi->cabinet) - { - if (mi->cabinet[0] == '#') - { - r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source); - if (r != ERROR_SUCCESS) - { - ERR("Failed to extract cabinet stream\n"); - return ERROR_FUNCTION_FAILED; - } - } - else - lstrcatW(mi->source, mi->cabinet); - } - options = MSICODE_PRODUCT; if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) { @@ -595,7 +672,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO } else { - source = mi->source; + source = mi->sourcedir; options |= MSISOURCETYPE_NETWORK; } @@ -610,7 +687,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO return ERROR_SUCCESS; } -/* FIXME: search NETWORK and URL sources as well */ +/* FIXME: search URL sources as well */ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) { WCHAR source[MAX_PATH]; @@ -618,8 +695,16 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) WCHAR prompt[MAX_PATH]; DWORD volumesz, promptsz; DWORD index, size, id; + WCHAR last_type[2]; UINT r; + size = 2; + r = MsiSourceListGetInfoW(package->ProductCode, NULL, + package->Context, MSICODE_PRODUCT, + INSTALLPROPERTY_LASTUSEDTYPEW, last_type, &size); + if (r != ERROR_SUCCESS) + return r; + size = MAX_PATH; r = MsiSourceListGetInfoW(package->ProductCode, NULL, package->Context, MSICODE_PRODUCT, @@ -627,6 +712,26 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (r != ERROR_SUCCESS) return r; + index = 0; + volumesz = MAX_PATH; + promptsz = MAX_PATH; + + if (last_type[0] == 'n') + { + while (MsiSourceListEnumSourcesW(package->ProductCode, NULL, + package->Context, + MSISOURCETYPE_NETWORK, index++, + volume, &volumesz) == ERROR_SUCCESS) + { + if (!strncmpiW(source, volume, strlenW(source))) + { + lstrcpyW(mi->sourcedir, source); + TRACE("Found network source %s\n", debugstr_w(mi->sourcedir)); + return ERROR_SUCCESS; + } + } + } + index = 0; volumesz = MAX_PATH; promptsz = MAX_PATH; @@ -644,7 +749,8 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) if (source_matches_volume(mi, source)) { /* FIXME: what about SourceDir */ - lstrcpyW(mi->source, source); + lstrcpyW(mi->sourcedir, source); + TRACE("Found disk source %s\n", debugstr_w(mi->sourcedir)); return ERROR_SUCCESS; } } @@ -655,6 +761,7 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) { UINT rc = ERROR_SUCCESS; + WCHAR *cabinet_file; /* media info for continuous cabinet is already loaded */ if (mi->is_continuous) @@ -663,7 +770,7 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) rc = msi_load_media_info(package, file, mi); if (rc != ERROR_SUCCESS) { - ERR("Unable to load media info\n"); + ERR("Unable to load media info %u\n", rc); return ERROR_FUNCTION_FAILED; } @@ -671,15 +778,24 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) if (!mi->cabinet || mi->cabinet[0] == '#') return ERROR_SUCCESS; + cabinet_file = get_cabinet_filename(mi); + /* package should be downloaded */ if (file->IsCompressed && - GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES && + GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES && package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL)) { - WCHAR temppath[MAX_PATH]; + WCHAR temppath[MAX_PATH], *p; - msi_download_file(mi->source, temppath); - lstrcpyW(mi->source, temppath); + msi_download_file(cabinet_file, temppath); + if ((p = strrchrW(temppath, '\\'))) *p = 0; + + msi_free(mi->sourcedir); + strcpyW(mi->sourcedir, temppath); + msi_free(mi->cabinet); + strcpyW(mi->cabinet, p + 1); + + msi_free(cabinet_file); return ERROR_SUCCESS; } @@ -687,7 +803,7 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) if (mi->volume_label && mi->disk_id > 1 && lstrcmpW(mi->first_volume, mi->volume_label)) { - LPWSTR source = msi_dup_property(package, cszSourceDir); + LPWSTR source = msi_dup_property(package->db, cszSourceDir); BOOL matches; matches = source_matches_volume(mi, source); @@ -697,20 +813,25 @@ UINT ready_media(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) { rc = msi_change_media(package, mi); if (rc != ERROR_SUCCESS) + { + msi_free(cabinet_file); return rc; + } } } if (file->IsCompressed && - GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) + GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES) { rc = find_published_source(package, mi); if (rc != ERROR_SUCCESS) { - ERR("Cabinet not found: %s\n", debugstr_w(mi->source)); + ERR("Cabinet not found: %s\n", debugstr_w(cabinet_file)); + msi_free(cabinet_file); return ERROR_INSTALL_FAILURE; } } + msi_free(cabinet_file); return ERROR_SUCCESS; } diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c index 07356405718..9d8a88a48fe 100644 --- a/dll/win32/msi/msi.c +++ b/dll/win32/msi/msi.c @@ -305,9 +305,8 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS UINT r = ERROR_SUCCESS, type; DWORD size = 0; LPCWSTR cmd_ptr = szCommandLine; - LPCWSTR product_code = szProductCode; - LPWSTR beg, end; - LPWSTR cmd = NULL, codes = NULL; + LPWSTR beg, end, cmd = NULL, codes = NULL; + BOOL succeeded = FALSE; static const WCHAR patcheq[] = {'P','A','T','C','H','=',0}; static WCHAR empty[] = {0}; @@ -342,8 +341,6 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size); if (r != ERROR_SUCCESS) goto done; - - product_code = codes; } if (!szCommandLine) @@ -362,16 +359,25 @@ static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWS lstrcatW(cmd, patcheq); lstrcatW(cmd, szPatchPackage); - beg = codes; - while ((end = strchrW(beg, '}'))) + if (szProductCode) + r = MsiConfigureProductExW(szProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); + else { - *(end + 1) = '\0'; + beg = codes; + while ((end = strchrW(beg, '}'))) + { + *(end + 1) = '\0'; + r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); + if (r == ERROR_SUCCESS) + { + TRACE("patch applied\n"); + succeeded = TRUE; + } + beg = end + 2; + } - r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd); - if (r != ERROR_SUCCESS) - goto done; - - beg = end + 2; + if (succeeded) + r = ERROR_SUCCESS; } done: @@ -480,10 +486,43 @@ UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR szPatchPackages, UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo) { - FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath), - cPatchInfo, pPatchInfo); + UINT i, r; + WCHAR *package_path = NULL; + MSIPATCHSEQUENCEINFOW *psi; - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("(%s, %d, %p)\n", debugstr_a(szProductPackagePath), cPatchInfo, pPatchInfo); + + if (szProductPackagePath && !(package_path = strdupAtoW( szProductPackagePath ))) + return ERROR_OUTOFMEMORY; + + psi = msi_alloc( cPatchInfo * sizeof(*psi) ); + if (!psi) + { + msi_free( package_path ); + return ERROR_OUTOFMEMORY; + } + + for (i = 0; i < cPatchInfo; i++) + { + psi[i].szPatchData = strdupAtoW( pPatchInfo[i].szPatchData ); + psi[i].ePatchDataType = pPatchInfo[i].ePatchDataType; + } + + r = MsiDetermineApplicablePatchesW( package_path, cPatchInfo, psi ); + if (r == ERROR_SUCCESS) + { + for (i = 0; i < cPatchInfo; i++) + { + pPatchInfo[i].dwOrder = psi[i].dwOrder; + pPatchInfo[i].uStatus = psi[i].uStatus; + } + } + + msi_free( package_path ); + for (i = 0; i < cPatchInfo; i++) + msi_free( (WCHAR *)psi[i].szPatchData ); + msi_free( psi ); + return r; } static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch ) @@ -502,15 +541,14 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch ) si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); if (!si) { - r = ERROR_FUNCTION_FAILED; - goto done; + msiobj_release( &patch_db->hdr ); + return ERROR_FUNCTION_FAILED; } r = msi_check_patch_applicable( package, si ); if (r != ERROR_SUCCESS) TRACE("patch not applicable\n"); -done: msiobj_release( &patch_db->hdr ); msiobj_release( &si->hdr ); return r; @@ -596,10 +634,6 @@ static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context, WCHAR sourcepath[MAX_PATH]; WCHAR filename[MAX_PATH]; - static const WCHAR szLocalPackage[] = { - 'L','o','c','a','l','P','a','c','k','a','g','e',0}; - - r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE); if (r != ERROR_SUCCESS) return ERROR_BAD_CONFIGURATION; @@ -1181,7 +1215,7 @@ done: static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size) { - UINT r; + UINT r = ERROR_SUCCESS; if (!val) return ERROR_UNKNOWN_PROPERTY; @@ -1201,7 +1235,7 @@ static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size) if (size) *size = lstrlenW(val); - return ERROR_SUCCESS; + return r; } UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid, @@ -2149,6 +2183,22 @@ UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uT return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId); } +UINT WINAPI MsiMessageBoxExA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, + DWORD unknown, WORD wLanguageId, DWORD f) +{ + FIXME("(%p, %s, %s, %u, 0x%08x, 0x%08x, 0x%08x): semi-stub\n", hWnd, debugstr_a(lpText), + debugstr_a(lpCaption), uType, unknown, wLanguageId, f); + return MessageBoxExA(hWnd, lpText, lpCaption, uType, wLanguageId); +} + +UINT WINAPI MsiMessageBoxExW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, + DWORD unknown, WORD wLanguageId, DWORD f) +{ + FIXME("(%p, %s, %s, %u, 0x%08x, 0x%08x, 0x%08x): semi-stub\n", hWnd, debugstr_w(lpText), + debugstr_w(lpCaption), uType, unknown, wLanguageId, f); + return MessageBoxExW(hWnd, lpText, lpCaption, uType, wLanguageId); +} + UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext, DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf, LPDWORD pcchPathBuf ) @@ -2337,6 +2387,7 @@ done: r = ERROR_SUCCESS; } + msiobj_release(&package->hdr); return r; } @@ -3519,10 +3570,10 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, if (r != ERROR_SUCCESS) return r; - MSI_SetPropertyW( package, szReinstallMode, reinstallmode ); - MSI_SetPropertyW( package, szInstalled, szOne ); - MSI_SetPropertyW( package, szLogVerbose, szOne ); - MSI_SetPropertyW( package, szReinstall, szFeature ); + msi_set_property( package->db, szReinstallMode, reinstallmode ); + msi_set_property( package->db, szInstalled, szOne ); + msi_set_property( package->db, szLogVerbose, szOne ); + msi_set_property( package->db, szReinstall, szFeature ); r = MSI_InstallPackage( package, sourcepath, NULL ); diff --git a/dll/win32/msi/msi.spec b/dll/win32/msi/msi.spec index 30daec931a6..94e3ed3cb23 100644 --- a/dll/win32/msi/msi.spec +++ b/dll/win32/msi/msi.spec @@ -272,8 +272,8 @@ 276 stub MsiSourceListClearMediaDiskW 277 stdcall MsiDetermineApplicablePatchesA(str long ptr) 278 stdcall MsiDetermineApplicablePatchesW(wstr long ptr) -279 stub MsiMessageBoxExA -280 stub MsiMessageBoxExW +279 stdcall MsiMessageBoxExA(long str str long long long long) +280 stdcall MsiMessageBoxExW(long wstr wstr long long long long) 281 stdcall MsiSetExternalUIRecord(ptr long ptr ptr) @ stdcall -private DllCanUnloadNow() diff --git a/dll/win32/msi/msi_Bg.rc b/dll/win32/msi/msi_Bg.rc index d3b8ca84abb..8aea16940f3 100644 --- a/dll/win32/msi/msi_Bg.rc +++ b/dll/win32/msi/msi_Bg.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "ďúň˙ň %s íĺ ĺ íŕěĺđĺí" 9 "ďîńňŕâĺňĺ äčńę %s" - 10 "íĺęîđĺęňíč ďŕđŕěĺňđč" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "âúâĺäĺňĺ ďŕďęŕňŕ, ęî˙ňî ńúäúđćŕ %s" 12 "čçňî÷íčęŕ çŕ číńňŕëŕöč˙ íŕ ôóíęöčîíŕëíîńňňŕ ëčďńâŕ" 13 "ěđĺćîâîňî óńňđîéńňâŕ íóćíî çŕ ôóíęöčîíŕëíîńňňŕ ëčďńâŕ " diff --git a/dll/win32/msi/msi_Da.rc b/dll/win32/msi/msi_Da.rc index beee42765ee..fa7e1c43c39 100644 --- a/dll/win32/msi/msi_Da.rc +++ b/dll/win32/msi/msi_Da.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "Kunne ikke ĺbne den specificerede installationspakke. Kontroller stien og prřv igen." 5 "kunne ikke finden stien '%s'." 9 "indsćt disk '%s'" - 10 "forkerte parametere." + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "angiv kataloget som indeholder '%s'." 12 "featurens installationskilde mangler." 13 "featurens netvćrksdrev mangler." diff --git a/dll/win32/msi/msi_De.rc b/dll/win32/msi/msi_De.rc index e0cccf07806..e07b5efd127 100644 --- a/dll/win32/msi/msi_De.rc +++ b/dll/win32/msi/msi_De.rc @@ -2,6 +2,7 @@ * German resources for MSI * * Copyright 2005 Henning Gerhardt + * Copyright 2010 Detlef Riekenberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Das angegebene Installationspaket konnte nicht geöffnet werden. Bitte ĂĽberprĂĽfen Sie den Pfadnamen und versuchen Sie es noch einmal." 5 "Der Pfad %s wurde nicht gefunden." 9 "Bitte Disk %s einlegen." - 10 "Falsche Parameter" + 10 "Windows Installer %s\n\n" \ + "Benutzung:\n" \ + "msiexec Befehl {Parameter} [Zusätzliche Parammeter]\n\n" \ + "Produkt installieren:\n" \ + "\t/i {Paket|Produktcode} [Eigenschaft]\n" \ + "\t/package {Paket|Produktcode} [Eigenschaft]\n" \ + "\t/a Paket [Eigenschaft]\n" \ + "Installation reparieren:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {Paket|Produktcode}\n" \ + "Produkt deinstallieren:\n" \ + "\t/uninstall {Paket|Produktcode} [Eigenschaft]\n" \ + "\t/x {Paket|Produktcode} [Eigenschaft]\n" \ + "Produkt ankĂĽndigen:\n" \ + "\t/j[u|m] Paket [/t Transformationspaket] [/g Sprachkennung]\n" \ + "Patch integrieren:\n" \ + "\t/p Patchpaket [Eigenschaft]\n" \ + "\t/p Patchpaket /a Paket [Eigenschaft]\n" \ + "Protokollierung und Benutzeroberfläche fĂĽr die oberen Befehle anpassen:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] Protokolldatei\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "MSI Service registrieren:\n" \ + "\t/y\n" \ + "Registrierung des MSI Service aufheben:\n" \ + "\t/z\n" \ + "Hilfe anzeigen:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Geben Sie das Verzeichnis ein, dass %s enthält." 12 "Die Installationsquelle fĂĽr das Feature fehlt." 13 "Das Netzwerklaufwerk fĂĽr das Feature fehlt." diff --git a/dll/win32/msi/msi_En.rc b/dll/win32/msi/msi_En.rc index 74fc5c14a85..c506e003445 100644 --- a/dll/win32/msi/msi_En.rc +++ b/dll/win32/msi/msi_En.rc @@ -2,6 +2,7 @@ * English resources for MSI * * Copyright 2005 Mike McCormack + * Copyright 2010 Detlef Riekenberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "path %s not found" 9 "insert disk %s" - 10 "bad parameters" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parameter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "enter which folder contains %s" 12 "install source for feature missing" 13 "network drive for feature missing" diff --git a/dll/win32/msi/msi_Eo.rc b/dll/win32/msi/msi_Eo.rc index 7579bdc65cb..8b8c8d36fbd 100644 --- a/dll/win32/msi/msi_Eo.rc +++ b/dll/win32/msi/msi_Eo.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "Mi ne trovis la vojon %s" 9 "enţovu la diskon %s" - 10 "nekorektaj parametroj" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "enigu la nomon de dosierujo kiu enhavas %s" 12 "instalad-fonto por mankanta taýgeco" 13 "retdrajvo por mankanta taýgeco" diff --git a/dll/win32/msi/msi_Es.rc b/dll/win32/msi/msi_Es.rc index 781be071802..f5425dbb654 100644 --- a/dll/win32/msi/msi_Es.rc +++ b/dll/win32/msi/msi_Es.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "No se ha podido abrir el paquete de instalación especificado. Por favor, compruebe la ruta del archivo y vuelva a intentarlo." 5 "ruta %s no encontrada" 9 "inserte el disco %s" - 10 "parámetros incorrectos" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "introduzca qué carpeta contiene %s" 12 "instalar fuente para característica ausente" 13 "unidad de red para característica ausente" diff --git a/dll/win32/msi/msi_Fi.rc b/dll/win32/msi/msi_Fi.rc index 17721aa4b01..f3d58bff2bc 100644 --- a/dll/win32/msi/msi_Fi.rc +++ b/dll/win32/msi/msi_Fi.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "Polkua %s ei löydy." 9 "Anna levy %s" - 10 "Virheelliset parametrit." + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Anna kansio, joka sisältää %s" 12 "Ominaisuuden asennuslähde puuttuu." 13 "Ominaisuuden verkkolevy puuttuu." diff --git a/dll/win32/msi/msi_Fr.rc b/dll/win32/msi/msi_Fr.rc index f7f733803bc..6cd1fc5ca21 100644 --- a/dll/win32/msi/msi_Fr.rc +++ b/dll/win32/msi/msi_Fr.rc @@ -2,6 +2,7 @@ * French resources for MSI * * Copyright 2005 Jonathan Ernst + * Copyright 2009-2010 FrĂ©dĂ©ric Delanoy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +31,33 @@ STRINGTABLE DISCARDABLE 4 "Le paquet d'installation spĂ©cifiĂ© n'a pu ĂŞtre ouvert. Veuillez vĂ©rifier le chemin du fichier et rĂ©essayer." 5 "Le chemin %s est introuvable" 9 "insĂ©rez le disque %s" - 10 "mauvais paramètres" + 10 "Programme d'installation Windows %s\n\n" \ + "Usage :\n" \ + "msiexec commande {paramètre obligatoire} [paramètre optionnel]\n\n" \ + "Installer un produit :\n" \ + "\t/i {paquet|code_produit} [propriĂ©tĂ©]\n" \ + "\t/package {paquet|code_produit} [propriĂ©tĂ©]\n" \ + "\t/a paquet [propriĂ©tĂ©]\n" \ + "RĂ©parer une installation :\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {paquet|code_produit}\n" \ + "DĂ©sinstaller un produit :\n" \ + "\t/uninstall {paquet|code_produit} [propriĂ©tĂ©]\n" \ + "\t/x {paquet|code_produit} [propriĂ©tĂ©]\n" \ + "Publier un produit :\n" \ + "\t/j[u|m] paquet [/t transformation] [/g id_langue]\n" \ + "Appliquer un patch :\n" \ + "\t/p paquet_patch [propriĂ©tĂ©]\n" \ + "\t/p paquet_patch /a paquet [propriĂ©tĂ©]\n" \ + "Modificateurs de journalisation et d'interface utilisateur pour les commandes ci-dessus :\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] fichier_journal\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Enregistrer le service MSI :\n" \ + "\t/y\n" \ + "Annuler l'enregistrement du service MSI :\n" \ + "\t/z\n" \ + "Afficher cette aide :\n" \ + "\t/help\n" \ + "\t/?\n" 11 "saisissez le nom du dossier contenant %s" 12 "source d'installation pour la fonctionnalitĂ© manquante" 13 "lecteur rĂ©seau pour la fonctionnalitĂ© manquante" diff --git a/dll/win32/msi/msi_Hu.rc b/dll/win32/msi/msi_Hu.rc index 21ba5cf30c1..846de4ccada 100644 --- a/dll/win32/msi/msi_Hu.rc +++ b/dll/win32/msi/msi_Hu.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "%s útvonal nem található" 9 "helyezze be a lemezt: %s" - 10 "rossz paraméterek" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "adja meg melyik mappa tartalmazza ezt: %s" 12 "hiányzó tulajdonság a telepítési forráshoz" 13 "hiányzó tulajdonság a hálózati meghajtóhoz" diff --git a/dll/win32/msi/msi_It.rc b/dll/win32/msi/msi_It.rc index a40a7303425..0586bb4bab5 100644 --- a/dll/win32/msi/msi_It.rc +++ b/dll/win32/msi/msi_It.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Impossibile aprire il pacchetto di installazione specificato. Per favore controlla l'indirizzo del file e riprova." 5 "percorso %s non trovato" 9 "inserire disco %s" - 10 "parametri incorretti" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "immettere il nome della cartella che contiene %s" 12 "sorgente di installazione per la funzionalitĂ  mancante" 13 "periferica di rete per la funzionalitĂ  mancante" diff --git a/dll/win32/msi/msi_Ko.rc b/dll/win32/msi/msi_Ko.rc index ca14253307d..17ab488ce2f 100644 --- a/dll/win32/msi/msi_Ko.rc +++ b/dll/win32/msi/msi_Ko.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 " ÁöÁ¤ÇŃ ĽłÄˇ ĆĐŰÁö¸¦ ż­ Ľö ľř˝Ŕ´Ď´Ů. ĆÄŔĎ °ć·Î¸¦ Č®ŔÎÇĎ°í ´Ů˝Ă ˝ĂµµÇϽʽÿŔ." 5 "%s °ć·Î¸¦ ĂŁŔ»Ľö ľř˝Ŕ´Ď´Ů" 9 "µđ˝şĹ© %s »đŔÔ" - 10 "Ŕ߸řµČ ¸Ĺ°łşŻĽö" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "%s¸¦ Ć÷ÇÔÇĎ´Â Ćú´ő¸¦ ŔÔ·ÂÇĎĽĽż©" 12 "şüÁř şÎşĐ(feature)Ŕ» Ŕ§ÇŃ ĽłÄˇ żřş»" 13 "şüÁř şÎşĐ(feature)Ŕ» Ŕ§ÇŃ ł×Ć®żöĹ© µĺ¶óŔĚşę" diff --git a/dll/win32/msi/msi_Lt.rc b/dll/win32/msi/msi_Lt.rc index 1cf1c52924e..c88592c49bc 100644 --- a/dll/win32/msi/msi_Lt.rc +++ b/dll/win32/msi/msi_Lt.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Nepavyko atverti nurodyto diegimo paketo. Patikrinkite failo keliÄ… ir mÄ—ginkite dar kartÄ…." 5 "kelias %s nerastas" 9 "ÄŻdÄ—kite diskÄ… %s" - 10 "blogi parametrai" + 10 "Windows diegimo programa %s\n\n" \ + "Naudojimas:\n" \ + "msiexec komanda {bĹ«tinas parametras} [nebĹ«tinas parametras]\n\n" \ + "Ä®diegti produktÄ…:\n" \ + "\t/i {paketas|produkto_kodas} [savybÄ—]\n" \ + "\t/package {paketas|produkto_kodas} [savybÄ—]\n" \ + "\t/a paketas [savybÄ—]\n" \ + "Taisyti ÄŻdiegimÄ…:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {paketas|produkto_kodas}\n" \ + "Pašalinti produktÄ…:\n" \ + "\t/uninstall {paketas|produkto_kodas} [savybÄ—]\n" \ + "\t/x {paketas|produkto_kodas} [savybÄ—]\n" \ + "Skelbti produktÄ…:\n" \ + "\t/j[u|m] paketas [/t pakeitimas] [/g kalbos_identifikatorius]\n" \ + "Pritaikyti pataisÄ…:\n" \ + "\t/p pataisos_paketas [savybÄ—]\n" \ + "\t/p pataisos_paketas /a paketas [savybÄ—]\n" \ + "Ĺ˝urnalo ir sÄ…sajos modifikatoriai aukščiau išvardintoms komandoms:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] Ĺľurnalo_failas\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Registruoti MSI tarnybÄ…:\n" \ + "\t/y\n" \ + "Išregistruoti MSI tarnybÄ…:\n" \ + "\t/z\n" \ + "Parodyti šiÄ… pagalbÄ…:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "ÄŻveskite aplankÄ…, kuris turi %s" 12 "trĹ«ksta diegimo šaltinio komponentui" 13 "trĹ«ksta tinklo disko komponentui" diff --git a/dll/win32/msi/msi_Nl.rc b/dll/win32/msi/msi_Nl.rc index da304304ed3..306cfd7e30a 100644 --- a/dll/win32/msi/msi_Nl.rc +++ b/dll/win32/msi/msi_Nl.rc @@ -1,5 +1,5 @@ /* - * Durch resources for MSI + * Dutch resources for MSI * * Copyright 2005 Hans Leidekker * @@ -24,13 +24,39 @@ LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { - 4 "The specified installation package could not be opened. Please check the file path and try again." + 4 "Het opgegeven installatie pakket kon niet worden geopend. Verifieer het bestandspad en probeer opnieuw." 5 "Pad %s niet gevonden" 9 "Plaats disk %s" - 10 "Ongeldige parameters" + 10 "Windows Installer %s\n\n" \ + "Gebruik:\n" \ + "msiexec commando {vereiste parameter} [optionele parameter]\n\n" \ + "Installeer een product:\n" \ + "\t/i {pakket|productcode} [eigenschap]\n" \ + "\t/package {pakket|productcode} [eigenschap]\n" \ + "\t/a pakket [eigenschap]\n" \ + "Herstel een installatie:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {pakket|productcode}\n" \ + "Verwijder een product:\n" \ + "\t/uninstall {pakket|productcode} [eigenschap]\n" \ + "\t/x {pakket|productcode} [eigenschap]\n" \ + "Adverteer een product:\n" \ + "\t/j[u|m] pakket [/t transform] [/g languageid]\n" \ + "Pas een patch toe:\n" \ + "\t/p patchpakket [eigenschap]\n" \ + "\t/p patchpakket /a pakket [eigenschap]\n" \ + "Log en UI Modifiers voor bovenstaande commando's:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logbestand\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Registreer MSI Service:\n" \ + "\t/y\n" \ + "Maak registratie MSI Service ongedaan:\n" \ + "\t/z\n" \ + "Laat dit helpvenster zien:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Voer de map in die %s bevat" - 12 "De installatiebron van het feature ontbreekt" - 13 "De netwerkschijf met het feature ontbreekt" + 12 "De installatiebron van de feature ontbreekt" + 13 "De netwerkschijf met de feature ontbreekt" 14 "Feature van:" 15 "Kies de map die %s bevat" } diff --git a/dll/win32/msi/msi_No.rc b/dll/win32/msi/msi_No.rc index e885f5adbda..93e26c67211 100644 --- a/dll/win32/msi/msi_No.rc +++ b/dll/win32/msi/msi_No.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "Klarte ikke ĺpne den oppgitte installasjonspakken. Kontroller filbanen og prřv igjen." 5 "Fant ikke stien '%s'." 9 "Sett i disk '%s'" - 10 "Gale parametere." + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Oppgi katalogen som inneholder '%s'." 12 "Egenskapens installasjonskilde mangler." 13 "Egenskapens nettverksstasjon mangler." diff --git a/dll/win32/msi/msi_Pl.rc b/dll/win32/msi/msi_Pl.rc index c31311ebf7e..ceb64dd9c8c 100644 --- a/dll/win32/msi/msi_Pl.rc +++ b/dll/win32/msi/msi_Pl.rc @@ -28,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "Nie udało się otworzyć wybranego pakietu instalacyjnego. Sprawdź czy ścieżka jest poprawna i spróbuj ponownie." 5 "ścieżka '%s' nie została odnaleziona" 9 "włóż dysk '%s'" - 10 "złe parametry" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "wprowadź siceżkę do folderu zawierającego '%s'" 12 "źródło danych zawierające żądanę funkcję jest niedostępne" 13 "dysk siecowy zawierający żądaną funckje jest niedostępny" diff --git a/dll/win32/msi/msi_Pt.rc b/dll/win32/msi/msi_Pt.rc index 64ab16348d4..94cc6330e0c 100644 --- a/dll/win32/msi/msi_Pt.rc +++ b/dll/win32/msi/msi_Pt.rc @@ -28,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "caminho %s năo encontrado" 9 "insira disco %s" - 10 "parâmetros inválidos" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "entre qual pasta contém %s" 12 "instalar fonte para característica faltando" 13 "drive de rede para característica faltando" @@ -43,7 +69,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "localizaçăo %s năo encontrada" 9 "insira o disco %s" - 10 "parâmetros inválidos" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "indique que pasta contém %s" 12 "instalar fonte para a opçăo em falta" 13 "controlador de rede para a opçăo em falta" diff --git a/dll/win32/msi/msi_Ro.rc b/dll/win32/msi/msi_Ro.rc index b877b42a34e..ffd9c5e08d7 100644 --- a/dll/win32/msi/msi_Ro.rc +++ b/dll/win32/msi/msi_Ro.rc @@ -28,7 +28,33 @@ STRINGTABLE DISCARDABLE 4 "Pachetul de instalare menČ›ionat nu a putut fi deschis. VerificaČ›i calea Č™i Ă®ncercaČ›i din nou." 5 "calea %s nu a fost gÄsitÄ" 9 "inseraČ›i discul %s" - 10 "parameteri greČ™iČ›i" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "introduceČ›i fiČ™ierul care conČ›ine %s" 12 "lipseČ™te sursa de instalare pentru aceastÄ caracteristicÄ" 13 "lipseČ™te unitatea de reČ›ea pentru aceastÄ caracteristicÄ" diff --git a/dll/win32/msi/msi_Ru.rc b/dll/win32/msi/msi_Ru.rc index 8e7aafdda31..7cd4a2b0737 100644 --- a/dll/win32/msi/msi_Ru.rc +++ b/dll/win32/msi/msi_Ru.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "Указанный пакет не может быть открыт. Проверьте файл и повторите попыткŃ." 5 "ĐżŃть %s не найден" 9 "вŃтавьте диŃĐş %s" - 10 "неверные параметры" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "Ńкажите каталог, Ńодержащий %s" 12 "иŃточник ŃŃтановки данной возможноŃти не Ńказан" 13 "Ńетевой диŃĐş для данной возможноŃти не Ńказан" diff --git a/dll/win32/msi/msi_Si.rc b/dll/win32/msi/msi_Si.rc index 75823390635..3477f1ba6e5 100644 --- a/dll/win32/msi/msi_Si.rc +++ b/dll/win32/msi/msi_Si.rc @@ -29,7 +29,33 @@ STRINGTABLE DISCARDABLE 4 "Navedenega namestitvenega paketa ni mogoÄŤe odpreti. Preverite ime datoteke in poskusite znova." 5 "pot %s ne obstaja" 9 "vnesite disk %s" - 10 "neveljavni parametri" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "vnesite ime mape, ki vsebuje %s" 12 "manjkajoÄŤ namestitveni vir za namestitev funkcije" 13 "manjkajoÄŤ omreĹľni pogon za namestitev funkcijo" diff --git a/dll/win32/msi/msi_Sv.rc b/dll/win32/msi/msi_Sv.rc index 47bf09b00c4..4c37cfc475b 100644 --- a/dll/win32/msi/msi_Sv.rc +++ b/dll/win32/msi/msi_Sv.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "Det angivna installationspaketet kunde inte öppnas. Kontrollera filsökvägen och försök igen." 5 "sökvägen %s hittades inte" 9 "mata in %s" - 10 "felaktiga parametrar" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "ange vilken mapp som innehĺller %s" 12 "installationskälla för funktion saknar" 13 "nätverksenhet för funktion saknar" diff --git a/dll/win32/msi/msi_Tr.rc b/dll/win32/msi/msi_Tr.rc index a8e0f369666..c6a12c1ae07 100644 --- a/dll/win32/msi/msi_Tr.rc +++ b/dll/win32/msi/msi_Tr.rc @@ -27,7 +27,33 @@ STRINGTABLE DISCARDABLE 4 "The specified installation package could not be opened. Please check the file path and try again." 5 "%s yolu bulunamadý" 9 "%s nolu diski yerleţtirin" - 10 "bozuk parametreler" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "%s öđesini içeren dizini girin" 12 "eksik özellik için kurulum kaynađý" 13 "eksik özellik için ađ sürücüsü" diff --git a/dll/win32/msi/msi_Uk.rc b/dll/win32/msi/msi_Uk.rc index 4b7173e8d4a..2407bbe6e6d 100644 --- a/dll/win32/msi/msi_Uk.rc +++ b/dll/win32/msi/msi_Uk.rc @@ -32,7 +32,33 @@ STRINGTABLE DISCARDABLE 4 "Не вдалоŃŃŹ відкрити вказаний пакет Ń–Đ˝Ńталяції. Перевірте Ńлях Đ´Đľ Ń„Đ°ĐąĐ»Ń Ń‚Đ° ŃпробŃйте знов." 5 "Ńлях %s не знайдено" 9 "вŃтавте диŃĐş %s" - 10 "невірні параметри" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "вкажіть папкŃ, що ĐĽŃ–Ńтить %s" 12 "джерело вŃтановлення даної можливоŃті не вказане" 13 "мережевий диŃĐş для даної можливоŃті не вказаний" diff --git a/dll/win32/msi/msi_Zh.rc b/dll/win32/msi/msi_Zh.rc index a6d5cd1eff6..91fd5400258 100644 --- a/dll/win32/msi/msi_Zh.rc +++ b/dll/win32/msi/msi_Zh.rc @@ -30,7 +30,33 @@ STRINGTABLE DISCARDABLE 4 "不č˝ć‰“开所指定的安装软件包. 请检查文件路径ĺŽĺ†ŤčŻ•." 5 "č·Żĺľ„ %s 没找ĺ°" 9 "ćŹ’ĺ…Ąč˝Żç› %s" - 10 "错误参数" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "čľ“ĺ…ĄĺŚ…ĺ« %s 的文件夹" 12 "本功č˝çš„安装ćşä¸Ťĺ­ĺś¨" 13 "本功č˝çš„网络驱动器不ĺ­ĺś¨" @@ -45,7 +71,33 @@ STRINGTABLE DISCARDABLE 4 "不č˝é–‹ĺ•źć‰€ćŚ‡ĺ®šçš„ĺ®‰čŁťč»źä»¶ĺŚ…. 請檢查檔ćˇč·Żĺľ‘後再試." 5 "č·Żĺľ‘ %s 沒找ĺ°" 9 "插入軟碟 %s" - 10 "錯誤ĺŹć•¸" + 10 "Windows Installer %s\n\n" \ + "Usage:\n" \ + "msiexec command {required parameter} [optional parammeter]\n\n" \ + "Install a product:\n" \ + "\t/i {package|productcode} [property]\n" \ + "\t/package {package|productcode} [property]\n" \ + "\t/a package [property]\n" \ + "Repair an installation:\n" \ + "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \ + "Uninstall a product:\n" \ + "\t/uninstall {package|productcode} [property]\n" \ + "\t/x {package|productcode} [property]\n" \ + "Advertise a product:\n" \ + "\t/j[u|m] package [/t transform] [/g languageid]\n" \ + "Apply a patch:\n" \ + "\t/p patchpackage [property]\n" \ + "\t/p patchpackage /a package [property]\n" \ + "Log and UI Modifiers for above commands:\n" \ + "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \ + "\t/q{|n|b|r|f|n+|b+|b-}\n" \ + "Register MSI Service:\n" \ + "\t/y\n" \ + "Unregister MSI Service:\n" \ + "\t/z\n" \ + "Display this help:\n" \ + "\t/help\n" \ + "\t/?\n" 11 "čĽ¸ĺ…ĄĺŚ…ĺ« %s 的檔ćˇĺ¤ľ" 12 "本功č˝çš„安裝ćşä¸Ťĺ­ĺś¨" 13 "本功č˝çš„網路儲ĺ­ć§˝ä¸Ťĺ­ĺś¨" diff --git a/dll/win32/msi/msi_ros.diff b/dll/win32/msi/msi_ros.diff deleted file mode 100644 index 1e88f29fb3f..00000000000 --- a/dll/win32/msi/msi_ros.diff +++ /dev/null @@ -1,5400 +0,0 @@ -Index: cond.tab.c -=================================================================== ---- cond.tab.c (revision 31639) -+++ cond.tab.c (working copy) -@@ -0,0 +1,2439 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, or (at your option) -+ any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Bison version. */ -+#define YYBISON_VERSION "2.1" -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* Substitute the variable and function names. */ -+#define yyparse cond_parse -+#define yylex cond_lex -+#define yyerror cond_error -+#define yylval cond_lval -+#define yychar cond_char -+#define yydebug cond_debug -+#define yynerrs cond_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_XOR = 263, -+ COND_IMP = 264, -+ COND_EQV = 265, -+ COND_LT = 266, -+ COND_GT = 267, -+ COND_EQ = 268, -+ COND_NE = 269, -+ COND_GE = 270, -+ COND_LE = 271, -+ COND_ILT = 272, -+ COND_IGT = 273, -+ COND_IEQ = 274, -+ COND_INE = 275, -+ COND_IGE = 276, -+ COND_ILE = 277, -+ COND_LPAR = 278, -+ COND_RPAR = 279, -+ COND_TILDA = 280, -+ COND_SS = 281, -+ COND_ISS = 282, -+ COND_ILHS = 283, -+ COND_IRHS = 284, -+ COND_LHS = 285, -+ COND_RHS = 286, -+ COND_PERCENT = 287, -+ COND_DOLLARS = 288, -+ COND_QUESTION = 289, -+ COND_AMPER = 290, -+ COND_EXCLAM = 291, -+ COND_IDENT = 292, -+ COND_NUMBER = 293, -+ COND_LITER = 294, -+ COND_ERROR = 295 -+ }; -+#endif -+/* Tokens. */ -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_XOR 263 -+#define COND_IMP 264 -+#define COND_EQV 265 -+#define COND_LT 266 -+#define COND_GT 267 -+#define COND_EQ 268 -+#define COND_NE 269 -+#define COND_GE 270 -+#define COND_LE 271 -+#define COND_ILT 272 -+#define COND_IGT 273 -+#define COND_IEQ 274 -+#define COND_INE 275 -+#define COND_IGE 276 -+#define COND_ILE 277 -+#define COND_LPAR 278 -+#define COND_RPAR 279 -+#define COND_TILDA 280 -+#define COND_SS 281 -+#define COND_ISS 282 -+#define COND_ILHS 283 -+#define COND_IRHS 284 -+#define COND_LHS 285 -+#define COND_RHS 286 -+#define COND_PERCENT 287 -+#define COND_DOLLARS 288 -+#define COND_QUESTION 289 -+#define COND_AMPER 290 -+#define COND_EXCLAM 291 -+#define COND_IDENT 292 -+#define COND_NUMBER 293 -+#define COND_LITER 294 -+#define COND_ERROR 295 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "cond.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2003 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#define COBJMACROS -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "winuser.h" -+#include "msi.h" -+#include "msiquery.h" -+#include "objbase.h" -+#include "oleauto.h" -+ -+#include "msipriv.h" -+#include "msiserver.h" -+#include "wine/debug.h" -+#include "wine/unicode.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+static int cond_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_yyinput -+{ -+ MSIPACKAGE *package; -+ LPCWSTR str; -+ INT n; -+ MSICONDITION result; -+} COND_input; -+ -+struct cond_str { -+ LPCWSTR data; -+ INT len; -+}; -+ -+static LPWSTR COND_GetString( const struct cond_str *str ); -+static LPWSTR COND_GetLiteral( const struct cond_str *str ); -+static int cond_lex( void *COND_lval, COND_input *info); -+static const WCHAR szEmpty[] = { 0 }; -+ -+static INT compare_int( INT a, INT operator, INT b ); -+static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ); -+ -+static INT compare_and_free_strings( LPWSTR a, INT op, LPWSTR b, BOOL convert ) -+{ -+ INT r; -+ -+ r = compare_string( a, op, b, convert ); -+ msi_free( a ); -+ msi_free( b ); -+ return r; -+} -+ -+static BOOL num_from_prop( LPCWSTR p, INT *val ) -+{ -+ INT ret = 0, sign = 1; -+ -+ if (!p) -+ return FALSE; -+ if (*p == '-') -+ { -+ sign = -1; -+ p++; -+ } -+ if (!*p) -+ return FALSE; -+ while (*p) -+ { -+ if( *p < '0' || *p > '9' ) -+ return FALSE; -+ ret = ret*10 + (*p - '0'); -+ p++; -+ } -+ *val = ret*sign; -+ return TRUE; -+} -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 111 "cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+} YYSTYPE; -+/* Line 196 of yacc.c. */ -+#line 286 "cond.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 219 of yacc.c. */ -+#line 298 "cond.tab.c" -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#ifndef YY_ -+# if YYENABLE_NLS -+# if ENABLE_NLS -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# endif -+# endif -+# ifndef YY_ -+# define YY_(msgid) msgid -+# endif -+#endif -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# else -+# define YYSTACK_ALLOC alloca -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYINCLUDED_STDLIB_H -+# endif -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# ifndef YYSTACK_ALLOC_MAXIMUM -+ /* The OS might guarantee only one guard page at the bottom of the stack, -+ and a page size can be as small as 4096 bytes. So we cannot safely -+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number -+ to allow for a few compiler-allocated temporary stack slots. */ -+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ -+# endif -+# else -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# ifndef YYSTACK_ALLOC_MAXIMUM -+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) -+# endif -+# ifdef __cplusplus -+extern "C" { -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifndef YYFREE -+# define YYFREE free -+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void free (void *); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifdef __cplusplus -+} -+# endif -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short int yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short int yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 28 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 71 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 41 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 12 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 53 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 70 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 295 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -+ 35, 36, 37, 38, 39, 40 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned char yyprhs[] = -+{ -+ 0, 0, 3, 5, 6, 8, 12, 16, 20, 24, -+ 26, 30, 33, 35, 37, 41, 45, 49, 53, 57, -+ 61, 65, 69, 73, 77, 79, 81, 83, 85, 87, -+ 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, -+ 109, 111, 113, 115, 117, 119, 121, 124, 127, 130, -+ 133, 135, 138, 140 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yysigned_char yyrhs[] = -+{ -+ 42, 0, -1, 43, -1, -1, 44, -1, 43, 5, -+ 44, -1, 43, 9, 44, -1, 43, 8, 44, -1, -+ 43, 10, 44, -1, 45, -1, 44, 6, 45, -1, -+ 7, 45, -1, 49, -1, 47, -1, 49, 46, 49, -+ -1, 50, 46, 49, -1, 49, 46, 50, -1, 50, -+ 46, 50, -1, 50, 46, 48, -1, 48, 46, 50, -+ -1, 48, 46, 48, -1, 48, 46, 49, -1, 49, -+ 46, 48, -1, 23, 43, 24, -1, 13, -1, 14, -+ -1, 11, -1, 12, -1, 16, -1, 15, -1, 26, -+ -1, 19, -1, 20, -1, 17, -1, 18, -1, 22, -+ -1, 21, -1, 27, -1, 30, -1, 31, -1, 28, -+ -1, 29, -1, 50, -1, 48, -1, 39, -1, 52, -+ -1, 33, 51, -1, 34, 51, -1, 35, 51, -1, -+ 36, 51, -1, 51, -1, 32, 51, -1, 37, -1, -+ 38, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short int yyrline[] = -+{ -+ 0, 135, 135, 141, 148, 152, 156, 160, 164, 171, -+ 175, 182, 186, 190, 195, 199, 208, 217, 221, 225, -+ 229, 233, 238, 243, 251, 252, 253, 254, 255, 256, -+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, -+ 267, 268, 272, 276, 283, 292, 296, 305, 314, 327, -+ 339, 346, 360, 369 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR", -+ "COND_AND", "COND_NOT", "COND_XOR", "COND_IMP", "COND_EQV", "COND_LT", -+ "COND_GT", "COND_EQ", "COND_NE", "COND_GE", "COND_LE", "COND_ILT", -+ "COND_IGT", "COND_IEQ", "COND_INE", "COND_IGE", "COND_ILE", "COND_LPAR", -+ "COND_RPAR", "COND_TILDA", "COND_SS", "COND_ISS", "COND_ILHS", -+ "COND_IRHS", "COND_LHS", "COND_RHS", "COND_PERCENT", "COND_DOLLARS", -+ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT", -+ "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition", -+ "expression", "boolean_term", "boolean_factor", "operator", "value_s", -+ "literal", "value_i", "symbol_s", "identifier", "integer", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short int yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -+ 295 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 41, 42, 42, 43, 43, 43, 43, 43, 44, -+ 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, -+ 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, -+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -+ 46, 46, 47, 47, 48, 49, 49, 49, 49, 49, -+ 50, 50, 51, 52 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 0, 1, 3, 3, 3, 3, 1, -+ 3, 2, 1, 1, 3, 3, 3, 3, 3, 3, -+ 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, -+ 1, 2, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 3, 0, 0, 0, 0, 0, 0, 0, 52, 53, -+ 44, 0, 2, 4, 9, 13, 43, 12, 42, 50, -+ 45, 11, 0, 51, 46, 47, 48, 49, 1, 0, -+ 0, 0, 0, 0, 26, 27, 24, 25, 29, 28, -+ 33, 34, 31, 32, 36, 35, 30, 37, 40, 41, -+ 38, 39, 0, 0, 0, 23, 5, 7, 6, 8, -+ 10, 20, 21, 19, 22, 14, 16, 18, 15, 17 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yysigned_char yydefgoto[] = -+{ -+ -1, 11, 12, 13, 14, 52, 15, 16, 17, 18, -+ 19, 20 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -15 -+static const yysigned_char yypact[] = -+{ -+ -7, -7, -7, -14, -14, -14, -14, -14, -15, -15, -+ -15, 24, 46, 30, -15, -15, -9, -9, -9, -15, -+ -15, -15, 29, -15, -15, -15, -15, -15, -15, -7, -+ -7, -7, -7, -7, -15, -15, -15, -15, -15, -15, -+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, -+ -15, -15, 8, 8, 8, -15, 30, 30, 30, 30, -+ -15, -15, -15, -15, -15, -15, -15, -15, -15, -15 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yysigned_char yypgoto[] = -+{ -+ -15, -15, 50, 33, 0, -3, -15, -4, 14, 17, -+ 54, -15 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -1 -+static const unsigned char yytable[] = -+{ -+ 1, 21, 34, 35, 36, 37, 38, 39, 40, 41, -+ 42, 43, 44, 45, 53, 54, 2, 46, 47, 48, -+ 49, 50, 51, 8, 28, 3, 4, 5, 6, 7, -+ 8, 9, 10, 60, 29, 0, 33, 30, 31, 32, -+ 3, 4, 5, 6, 7, 8, 9, 10, 61, 64, -+ 67, 29, 22, 55, 30, 31, 32, 23, 24, 25, -+ 26, 27, 56, 57, 58, 59, 62, 65, 68, 63, -+ 66, 69 -+}; -+ -+static const yysigned_char yycheck[] = -+{ -+ 7, 1, 11, 12, 13, 14, 15, 16, 17, 18, -+ 19, 20, 21, 22, 17, 18, 23, 26, 27, 28, -+ 29, 30, 31, 37, 0, 32, 33, 34, 35, 36, -+ 37, 38, 39, 33, 5, -1, 6, 8, 9, 10, -+ 32, 33, 34, 35, 36, 37, 38, 39, 52, 53, -+ 54, 5, 2, 24, 8, 9, 10, 3, 4, 5, -+ 6, 7, 29, 30, 31, 32, 52, 53, 54, 52, -+ 53, 54 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 7, 23, 32, 33, 34, 35, 36, 37, 38, -+ 39, 42, 43, 44, 45, 47, 48, 49, 50, 51, -+ 52, 45, 43, 51, 51, 51, 51, 51, 0, 5, -+ 8, 9, 10, 6, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 26, 27, 28, 29, -+ 30, 31, 46, 46, 46, 24, 44, 44, 44, 44, -+ 45, 48, 49, 50, 48, 49, 50, 48, 49, 50 -+}; -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror (YY_("syntax error: cannot back up")); \ -+ YYERROR; \ -+ } \ -+while (0) -+ -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) -+#endif -+ -+ -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ -+ -+#ifndef YY_LOCATION_PRINT -+# if YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif -+ -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Type, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short int *bottom, short int *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short int *bottom; -+ short int *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned long int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ char *yyd = yydest; -+ const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+# ifndef yytnamerr -+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary -+ quotes and backslashes, so that it's suitable for yyerror. The -+ heuristic is that double-quoting is unnecessary unless the string -+ contains an apostrophe, a comma, or backslash (other than -+ backslash-backslash). YYSTR is taken from yytname. If YYRES is -+ null, do not copy; instead, return the length of what the result -+ would have been. */ -+static YYSIZE_T -+yytnamerr (char *yyres, const char *yystr) -+{ -+ if (*yystr == '"') -+ { -+ size_t yyn = 0; -+ char const *yyp = yystr; -+ -+ for (;;) -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } -+ do_not_strip_quotes: ; -+ } -+ -+ if (! yyres) -+ return yystrlen (yystr); -+ -+ return yystpcpy (yyres, yystr) - yyres; -+} -+# endif -+ -+#endif /* YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ -+# ifdef YYPRINT -+ if (yytype < YYNTOKENS) -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (!yymsg) -+ yymsg = "Deleting"; -+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ ; -+#endif -+#endif -+{ -+ /* The look-ahead symbol. */ -+int yychar; -+ -+/* The semantic value of the look-ahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ int yystate; -+ int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Look-ahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short int yyssa[YYINITDEPTH]; -+ short int *yyss = yyssa; -+ short int *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short int *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyexhaustedlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyexhaustedlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short int *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a look-ahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to look-ahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a look-ahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the look-ahead token. */ -+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 136 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ cond->result = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 3: -+#line 141 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ cond->result = MSICONDITION_NONE; -+ ;} -+ break; -+ -+ case 4: -+#line 149 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 5: -+#line 153 "cond.y" -+ { -+ (yyval.value) = (yyvsp[-2].value) || (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 6: -+#line 157 "cond.y" -+ { -+ (yyval.value) = !(yyvsp[-2].value) || (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 7: -+#line 161 "cond.y" -+ { -+ (yyval.value) = ( (yyvsp[-2].value) || (yyvsp[0].value) ) && !( (yyvsp[-2].value) && (yyvsp[0].value) ); -+ ;} -+ break; -+ -+ case 8: -+#line 165 "cond.y" -+ { -+ (yyval.value) = ( (yyvsp[-2].value) && (yyvsp[0].value) ) || ( !(yyvsp[-2].value) && !(yyvsp[0].value) ); -+ ;} -+ break; -+ -+ case 9: -+#line 172 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 10: -+#line 176 "cond.y" -+ { -+ (yyval.value) = (yyvsp[-2].value) && (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 11: -+#line 183 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value) ? 0 : 1; -+ ;} -+ break; -+ -+ case 12: -+#line 187 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value) ? 1 : 0; -+ ;} -+ break; -+ -+ case 13: -+#line 191 "cond.y" -+ { -+ (yyval.value) = ((yyvsp[0].string) && (yyvsp[0].string)[0]) ? 1 : 0; -+ msi_free((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 14: -+#line 196 "cond.y" -+ { -+ (yyval.value) = compare_int( (yyvsp[-2].value), (yyvsp[-1].value), (yyvsp[0].value) ); -+ ;} -+ break; -+ -+ case 15: -+#line 200 "cond.y" -+ { -+ int num; -+ if (num_from_prop( (yyvsp[-2].string), &num )) -+ (yyval.value) = compare_int( num, (yyvsp[-1].value), (yyvsp[0].value) ); -+ else -+ (yyval.value) = ((yyvsp[-1].value) == COND_NE || (yyvsp[-1].value) == COND_INE ); -+ msi_free((yyvsp[-2].string)); -+ ;} -+ break; -+ -+ case 16: -+#line 209 "cond.y" -+ { -+ int num; -+ if (num_from_prop( (yyvsp[0].string), &num )) -+ (yyval.value) = compare_int( (yyvsp[-2].value), (yyvsp[-1].value), num ); -+ else -+ (yyval.value) = ((yyvsp[-1].value) == COND_NE || (yyvsp[-1].value) == COND_INE ); -+ msi_free((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 17: -+#line 218 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), TRUE ); -+ ;} -+ break; -+ -+ case 18: -+#line 222 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), TRUE ); -+ ;} -+ break; -+ -+ case 19: -+#line 226 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), TRUE ); -+ ;} -+ break; -+ -+ case 20: -+#line 230 "cond.y" -+ { -+ (yyval.value) = compare_and_free_strings( (yyvsp[-2].string), (yyvsp[-1].value), (yyvsp[0].string), FALSE ); -+ ;} -+ break; -+ -+ case 21: -+#line 234 "cond.y" -+ { -+ (yyval.value) = 0; -+ msi_free((yyvsp[-2].string)); -+ ;} -+ break; -+ -+ case 22: -+#line 239 "cond.y" -+ { -+ (yyval.value) = 0; -+ msi_free((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 23: -+#line 244 "cond.y" -+ { -+ (yyval.value) = (yyvsp[-1].value); -+ ;} -+ break; -+ -+ case 24: -+#line 251 "cond.y" -+ { (yyval.value) = COND_EQ; ;} -+ break; -+ -+ case 25: -+#line 252 "cond.y" -+ { (yyval.value) = COND_NE; ;} -+ break; -+ -+ case 26: -+#line 253 "cond.y" -+ { (yyval.value) = COND_LT; ;} -+ break; -+ -+ case 27: -+#line 254 "cond.y" -+ { (yyval.value) = COND_GT; ;} -+ break; -+ -+ case 28: -+#line 255 "cond.y" -+ { (yyval.value) = COND_LE; ;} -+ break; -+ -+ case 29: -+#line 256 "cond.y" -+ { (yyval.value) = COND_GE; ;} -+ break; -+ -+ case 30: -+#line 257 "cond.y" -+ { (yyval.value) = COND_SS; ;} -+ break; -+ -+ case 31: -+#line 258 "cond.y" -+ { (yyval.value) = COND_IEQ; ;} -+ break; -+ -+ case 32: -+#line 259 "cond.y" -+ { (yyval.value) = COND_INE; ;} -+ break; -+ -+ case 33: -+#line 260 "cond.y" -+ { (yyval.value) = COND_ILT; ;} -+ break; -+ -+ case 34: -+#line 261 "cond.y" -+ { (yyval.value) = COND_IGT; ;} -+ break; -+ -+ case 35: -+#line 262 "cond.y" -+ { (yyval.value) = COND_ILE; ;} -+ break; -+ -+ case 36: -+#line 263 "cond.y" -+ { (yyval.value) = COND_IGE; ;} -+ break; -+ -+ case 37: -+#line 264 "cond.y" -+ { (yyval.value) = COND_ISS; ;} -+ break; -+ -+ case 38: -+#line 265 "cond.y" -+ { (yyval.value) = COND_LHS; ;} -+ break; -+ -+ case 39: -+#line 266 "cond.y" -+ { (yyval.value) = COND_RHS; ;} -+ break; -+ -+ case 40: -+#line 267 "cond.y" -+ { (yyval.value) = COND_ILHS; ;} -+ break; -+ -+ case 41: -+#line 268 "cond.y" -+ { (yyval.value) = COND_IRHS; ;} -+ break; -+ -+ case 42: -+#line 273 "cond.y" -+ { -+ (yyval.string) = (yyvsp[0].string); -+ ;} -+ break; -+ -+ case 43: -+#line 277 "cond.y" -+ { -+ (yyval.string) = (yyvsp[0].string); -+ ;} -+ break; -+ -+ case 44: -+#line 284 "cond.y" -+ { -+ (yyval.string) = COND_GetLiteral(&(yyvsp[0].str)); -+ if( !(yyval.string) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 45: -+#line 293 "cond.y" -+ { -+ (yyval.value) = (yyvsp[0].value); -+ ;} -+ break; -+ -+ case 46: -+#line 297 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ (yyval.value) = action; -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 47: -+#line 306 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetComponentStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ (yyval.value) = install; -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 48: -+#line 315 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ if (action == INSTALLSTATE_UNKNOWN) -+ (yyval.value) = MSICONDITION_FALSE; -+ else -+ (yyval.value) = action; -+ -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 49: -+#line 328 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; -+ -+ MSI_GetFeatureStateW(cond->package, (yyvsp[0].string), &install, &action ); -+ (yyval.value) = install; -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 50: -+#line 340 "cond.y" -+ { -+ COND_input* cond = (COND_input*) info; -+ -+ (yyval.string) = msi_dup_property( cond->package, (yyvsp[0].string) ); -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 51: -+#line 347 "cond.y" -+ { -+ UINT len = GetEnvironmentVariableW( (yyvsp[0].string), NULL, 0 ); -+ (yyval.string) = NULL; -+ if (len++) -+ { -+ (yyval.string) = msi_alloc( len*sizeof (WCHAR) ); -+ GetEnvironmentVariableW( (yyvsp[0].string), (yyval.string), len ); -+ } -+ msi_free( (yyvsp[0].string) ); -+ ;} -+ break; -+ -+ case 52: -+#line 361 "cond.y" -+ { -+ (yyval.string) = COND_GetString(&(yyvsp[0].str)); -+ if( !(yyval.string) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 53: -+#line 370 "cond.y" -+ { -+ LPWSTR szNum = COND_GetString(&(yyvsp[0].str)); -+ if( !szNum ) -+ YYABORT; -+ (yyval.value) = atoiW( szNum ); -+ msi_free( szNum ); -+ ;} -+ break; -+ -+ -+ default: break; -+ } -+ -+/* Line 1126 of yacc.c. */ -+#line 1740 "cond.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ int yytype = YYTRANSLATE (yychar); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); -+ YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; -+ int yysize_overflow = 0; -+ char *yymsg = 0; -+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 -+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; -+ int yyx; -+ -+#if 0 -+ /* This is so xgettext sees the translatable formats that are -+ constructed on the fly. */ -+ YY_("syntax error, unexpected %s"); -+ YY_("syntax error, unexpected %s, expecting %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -+#endif -+ char *yyfmt; -+ char const *yyf; -+ static char const yyunexpected[] = "syntax error, unexpected %s"; -+ static char const yyexpecting[] = ", expecting %s"; -+ static char const yyor[] = " or %s"; -+ char yyformat[sizeof yyunexpected -+ + sizeof yyexpecting - 1 -+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) -+ * (sizeof yyor - 1))]; -+ char const *yyprefix = yyexpecting; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 1; -+ -+ yyarg[0] = yytname[yytype]; -+ yyfmt = yystpcpy (yyformat, yyunexpected); -+ -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) -+ { -+ yycount = 1; -+ yysize = yysize0; -+ yyformat[sizeof yyunexpected - 1] = '\0'; -+ break; -+ } -+ yyarg[yycount++] = yytname[yyx]; -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ yyfmt = yystpcpy (yyfmt, yyprefix); -+ yyprefix = yyor; -+ } -+ -+ yyf = YY_(yyformat); -+ yysize1 = yysize + yystrlen (yyf); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ -+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg) -+ { -+ /* Avoid sprintf, as that infringes on the user's name space. -+ Don't have undefined behavior even if the translation -+ produced a string with the wrong number of "%s"s. */ -+ char *yyp = yymsg; -+ int yyi = 0; -+ while ((*yyp = *yyf)) -+ { -+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) -+ { -+ yyp += yytnamerr (yyp, yyarg[yyi++]); -+ yyf += 2; -+ } -+ else -+ { -+ yyp++; -+ yyf++; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ { -+ yyerror (YY_("syntax error")); -+ goto yyexhaustedlab; -+ } -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror (YY_("syntax error")); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse look-ahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } -+ else -+ { -+ yydestruct ("Error: discarding", yytoken, &yylval); -+ yychar = YYEMPTY; -+ } -+ } -+ -+ /* Else will try to reuse look-ahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+ /* Pacify compilers like GCC when the user code never invokes -+ YYERROR and the label yyerrorlab therefore never appears in user -+ code. */ -+ if (0) -+ goto yyerrorlab; -+ -+yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ -+ yydestruct ("Error: popping", yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Shift the error token. */ -+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*-------------------------------------------------. -+| yyexhaustedlab -- memory exhaustion comes here. | -+`-------------------------------------------------*/ -+yyexhaustedlab: -+ yyerror (YY_("memory exhausted")); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+ if (yychar != YYEOF && yychar != YYEMPTY) -+ yydestruct ("Cleanup: discarding lookahead", -+ yytoken, &yylval); -+ while (yyssp != yyss) -+ { -+ yydestruct ("Cleanup: popping", -+ yystos[*yyssp], yyvsp); -+ YYPOPSTACK; -+ } -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 379 "cond.y" -+ -+ -+ -+static int COND_IsAlpha( WCHAR x ) -+{ -+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) || -+ ( ( x >= 'a' ) && ( x <= 'z' ) ) || -+ ( ( x == '_' ) ) ); -+} -+ -+static int COND_IsNumber( WCHAR x ) -+{ -+ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') ); -+} -+ -+static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub ) -+{ -+ LPWSTR strlower, sublower, r; -+ strlower = CharLowerW( strdupW( str ) ); -+ sublower = CharLowerW( strdupW( sub ) ); -+ r = strstrW( strlower, sublower ); -+ if (r) -+ r = (LPWSTR)str + (r - strlower); -+ msi_free( strlower ); -+ msi_free( sublower ); -+ return r; -+} -+ -+static BOOL str_is_number( LPCWSTR str ) -+{ -+ int i; -+ -+ if (!*str) -+ return FALSE; -+ -+ for (i = 0; i < lstrlenW( str ); i++) -+ if (!isdigitW(str[i])) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b ) -+{ -+ int lhs, rhs; -+ -+ /* substring operators return 0 if LHS is missing */ -+ if (!a || !*a) -+ return 0; -+ -+ /* substring operators return 1 if RHS is missing */ -+ if (!b || !*b) -+ return 1; -+ -+ /* if both strings contain only numbers, use integer comparison */ -+ lhs = atoiW(a); -+ rhs = atoiW(b); -+ if (str_is_number(a) && str_is_number(b)) -+ return compare_int( lhs, operator, rhs ); -+ -+ switch (operator) -+ { -+ case COND_SS: -+ return strstrW( a, b ) ? 1 : 0; -+ case COND_ISS: -+ return strstriW( a, b ) ? 1 : 0; -+ case COND_LHS: -+ return 0 == strncmpW( a, b, lstrlenW( b ) ); -+ case COND_RHS: -+ return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b ); -+ case COND_ILHS: -+ return 0 == strncmpiW( a, b, lstrlenW( b ) ); -+ case COND_IRHS: -+ return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b ); -+ default: -+ ERR("invalid substring operator\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert ) -+{ -+ if (operator >= COND_SS && operator <= COND_RHS) -+ return compare_substring( a, operator, b ); -+ -+ /* null and empty string are equivalent */ -+ if (!a) a = szEmpty; -+ if (!b) b = szEmpty; -+ -+ if (convert && str_is_number(a) && str_is_number(b)) -+ return compare_int( atoiW(a), operator, atoiW(b) ); -+ -+ /* a or b may be NULL */ -+ switch (operator) -+ { -+ case COND_LT: -+ return -1 == lstrcmpW( a, b ); -+ case COND_GT: -+ return 1 == lstrcmpW( a, b ); -+ case COND_EQ: -+ return 0 == lstrcmpW( a, b ); -+ case COND_NE: -+ return 0 != lstrcmpW( a, b ); -+ case COND_GE: -+ return -1 != lstrcmpW( a, b ); -+ case COND_LE: -+ return 1 != lstrcmpW( a, b ); -+ case COND_ILT: -+ return -1 == lstrcmpiW( a, b ); -+ case COND_IGT: -+ return 1 == lstrcmpiW( a, b ); -+ case COND_IEQ: -+ return 0 == lstrcmpiW( a, b ); -+ case COND_INE: -+ return 0 != lstrcmpiW( a, b ); -+ case COND_IGE: -+ return -1 != lstrcmpiW( a, b ); -+ case COND_ILE: -+ return 1 != lstrcmpiW( a, b ); -+ default: -+ ERR("invalid string operator\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+ -+static INT compare_int( INT a, INT operator, INT b ) -+{ -+ switch (operator) -+ { -+ case COND_LT: -+ case COND_ILT: -+ return a < b; -+ case COND_GT: -+ case COND_IGT: -+ return a > b; -+ case COND_EQ: -+ case COND_IEQ: -+ return a == b; -+ case COND_NE: -+ case COND_INE: -+ return a != b; -+ case COND_GE: -+ case COND_IGE: -+ return a >= b; -+ case COND_LE: -+ case COND_ILE: -+ return a <= b; -+ case COND_SS: -+ case COND_ISS: -+ return ( a & b ) ? 1 : 0; -+ case COND_RHS: -+ return ( ( a & 0xffff ) == b ) ? 1 : 0; -+ case COND_LHS: -+ return ( ( (a>>16) & 0xffff ) == b ) ? 1 : 0; -+ default: -+ ERR("invalid integer operator\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+ -+static int COND_IsIdent( WCHAR x ) -+{ -+ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) -+ || ( x == '#' ) || (x == '.') ); -+} -+ -+static int COND_GetOperator( COND_input *cond ) -+{ -+ static const struct { -+ const WCHAR str[4]; -+ int id; -+ } table[] = { -+ { {'~','=',0}, COND_IEQ }, -+ { {'~','<','=',0}, COND_ILE }, -+ { {'~','>','<',0}, COND_ISS }, -+ { {'~','>','>',0}, COND_IRHS }, -+ { {'~','<','>',0}, COND_INE }, -+ { {'~','<',0}, COND_ILT }, -+ { {'~','>','=',0}, COND_IGE }, -+ { {'~','<','<',0}, COND_ILHS }, -+ { {'~','>',0}, COND_IGT }, -+ { {'>','=',0}, COND_GE }, -+ { {'>','<',0}, COND_SS }, -+ { {'<','<',0}, COND_LHS }, -+ { {'<','>',0}, COND_NE }, -+ { {'<','=',0}, COND_LE }, -+ { {'>','>',0}, COND_RHS }, -+ { {'>',0}, COND_GT }, -+ { {'<',0}, COND_LT }, -+ { {0}, 0 } -+ }; -+ LPCWSTR p = &cond->str[cond->n]; -+ int i = 0, len; -+ -+ while ( 1 ) -+ { -+ len = lstrlenW( table[i].str ); -+ if ( !len || 0 == strncmpW( table[i].str, p, len ) ) -+ break; -+ i++; -+ } -+ cond->n += len; -+ return table[i].id; -+} -+ -+static int COND_GetOne( struct cond_str *str, COND_input *cond ) -+{ -+ int rc, len = 1; -+ WCHAR ch; -+ -+ str->data = &cond->str[cond->n]; -+ -+ ch = str->data[0]; -+ -+ switch( ch ) -+ { -+ case 0: return 0; -+ case '(': rc = COND_LPAR; break; -+ case ')': rc = COND_RPAR; break; -+ case '&': rc = COND_AMPER; break; -+ case '!': rc = COND_EXCLAM; break; -+ case '$': rc = COND_DOLLARS; break; -+ case '?': rc = COND_QUESTION; break; -+ case '%': rc = COND_PERCENT; break; -+ case ' ': rc = COND_SPACE; break; -+ case '=': rc = COND_EQ; break; -+ -+ case '~': -+ case '<': -+ case '>': -+ rc = COND_GetOperator( cond ); -+ if (!rc) -+ rc = COND_ERROR; -+ return rc; -+ default: -+ rc = 0; -+ } -+ -+ if ( rc ) -+ { -+ cond->n += len; -+ return rc; -+ } -+ -+ if (ch == '"' ) -+ { -+ LPCWSTR p = strchrW( str->data + 1, '"' ); -+ if (!p) -+ return COND_ERROR; -+ len = p - str->data + 1; -+ rc = COND_LITER; -+ } -+ else if( COND_IsAlpha( ch ) ) -+ { -+ static const WCHAR szNot[] = {'N','O','T',0}; -+ static const WCHAR szAnd[] = {'A','N','D',0}; -+ static const WCHAR szXor[] = {'X','O','R',0}; -+ static const WCHAR szEqv[] = {'E','Q','V',0}; -+ static const WCHAR szImp[] = {'I','M','P',0}; -+ static const WCHAR szOr[] = {'O','R',0}; -+ -+ while( COND_IsIdent( str->data[len] ) ) -+ len++; -+ rc = COND_IDENT; -+ -+ if ( len == 3 ) -+ { -+ if ( !strncmpiW( str->data, szNot, len ) ) -+ rc = COND_NOT; -+ else if( !strncmpiW( str->data, szAnd, len ) ) -+ rc = COND_AND; -+ else if( !strncmpiW( str->data, szXor, len ) ) -+ rc = COND_XOR; -+ else if( !strncmpiW( str->data, szEqv, len ) ) -+ rc = COND_EQV; -+ else if( !strncmpiW( str->data, szImp, len ) ) -+ rc = COND_IMP; -+ } -+ else if( (len == 2) && !strncmpiW( str->data, szOr, len ) ) -+ rc = COND_OR; -+ } -+ else if( COND_IsNumber( ch ) ) -+ { -+ while( COND_IsNumber( str->data[len] ) ) -+ len++; -+ rc = COND_NUMBER; -+ } -+ else -+ { -+ ERR("Got unknown character %c(%x)\n",ch,ch); -+ return COND_ERROR; -+ } -+ -+ cond->n += len; -+ str->len = len; -+ -+ return rc; -+} -+ -+static int cond_lex( void *COND_lval, COND_input *cond ) -+{ -+ int rc; -+ struct cond_str *str = COND_lval; -+ -+ do { -+ rc = COND_GetOne( str, cond ); -+ } while (rc == COND_SPACE); -+ -+ return rc; -+} -+ -+static LPWSTR COND_GetString( const struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len+1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data, str->len * sizeof(WCHAR)); -+ ret[str->len]=0; -+ } -+ TRACE("Got identifier %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static LPWSTR COND_GetLiteral( const struct cond_str *str ) -+{ -+ LPWSTR ret; -+ -+ ret = msi_alloc( (str->len-1) * sizeof (WCHAR) ); -+ if( ret ) -+ { -+ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) ); -+ ret[str->len - 2]=0; -+ } -+ TRACE("Got literal %s\n",debugstr_w(ret)); -+ return ret; -+} -+ -+static int cond_error(const char *str) -+{ -+ TRACE("%s\n", str ); -+ return 0; -+} -+ -+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition ) -+{ -+ COND_input cond; -+ MSICONDITION r; -+ -+ TRACE("%s\n", debugstr_w( szCondition ) ); -+ -+ if ( szCondition == NULL ) -+ return MSICONDITION_NONE; -+ -+ cond.package = package; -+ cond.str = szCondition; -+ cond.n = 0; -+ cond.result = MSICONDITION_ERROR; -+ -+ if ( !cond_parse( &cond ) ) -+ r = cond.result; -+ else -+ r = MSICONDITION_ERROR; -+ -+ TRACE("%i <- %s\n", r, debugstr_w(szCondition)); -+ return r; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition ) -+{ -+ MSIPACKAGE *package; -+ UINT ret; -+ -+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE); -+ if( !package ) -+ { -+ HRESULT hr; -+ BSTR condition; -+ IWineMsiRemotePackage *remote_package; -+ -+ remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ); -+ if (!remote_package) -+ return MSICONDITION_ERROR; -+ -+ condition = SysAllocString( szCondition ); -+ if (!condition) -+ { -+ IWineMsiRemotePackage_Release( remote_package ); -+ return ERROR_OUTOFMEMORY; -+ } -+ -+ hr = IWineMsiRemotePackage_EvaluateCondition( remote_package, condition ); -+ -+ SysFreeString( condition ); -+ IWineMsiRemotePackage_Release( remote_package ); -+ -+ if (FAILED(hr)) -+ { -+ if (HRESULT_FACILITY(hr) == FACILITY_WIN32) -+ return HRESULT_CODE(hr); -+ -+ return ERROR_FUNCTION_FAILED; -+ } -+ -+ return ERROR_SUCCESS; -+ } -+ -+ ret = MSI_EvaluateConditionW( package, szCondition ); -+ msiobj_release( &package->hdr ); -+ return ret; -+} -+ -+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition ) -+{ -+ LPWSTR szwCond = NULL; -+ MSICONDITION r; -+ -+ szwCond = strdupAtoW( szCondition ); -+ if( szCondition && !szwCond ) -+ return MSICONDITION_ERROR; -+ -+ r = MsiEvaluateConditionW( hInstall, szwCond ); -+ msi_free( szwCond ); -+ return r; -+} -+ -Index: cond.tab.h -=================================================================== ---- cond.tab.h (revision 31639) -+++ cond.tab.h (working copy) -@@ -0,0 +1,132 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, or (at your option) -+ any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COND_SPACE = 258, -+ COND_EOF = 259, -+ COND_OR = 260, -+ COND_AND = 261, -+ COND_NOT = 262, -+ COND_XOR = 263, -+ COND_IMP = 264, -+ COND_EQV = 265, -+ COND_LT = 266, -+ COND_GT = 267, -+ COND_EQ = 268, -+ COND_NE = 269, -+ COND_GE = 270, -+ COND_LE = 271, -+ COND_ILT = 272, -+ COND_IGT = 273, -+ COND_IEQ = 274, -+ COND_INE = 275, -+ COND_IGE = 276, -+ COND_ILE = 277, -+ COND_LPAR = 278, -+ COND_RPAR = 279, -+ COND_TILDA = 280, -+ COND_SS = 281, -+ COND_ISS = 282, -+ COND_ILHS = 283, -+ COND_IRHS = 284, -+ COND_LHS = 285, -+ COND_RHS = 286, -+ COND_PERCENT = 287, -+ COND_DOLLARS = 288, -+ COND_QUESTION = 289, -+ COND_AMPER = 290, -+ COND_EXCLAM = 291, -+ COND_IDENT = 292, -+ COND_NUMBER = 293, -+ COND_LITER = 294, -+ COND_ERROR = 295 -+ }; -+#endif -+/* Tokens. */ -+#define COND_SPACE 258 -+#define COND_EOF 259 -+#define COND_OR 260 -+#define COND_AND 261 -+#define COND_NOT 262 -+#define COND_XOR 263 -+#define COND_IMP 264 -+#define COND_EQV 265 -+#define COND_LT 266 -+#define COND_GT 267 -+#define COND_EQ 268 -+#define COND_NE 269 -+#define COND_GE 270 -+#define COND_LE 271 -+#define COND_ILT 272 -+#define COND_IGT 273 -+#define COND_IEQ 274 -+#define COND_INE 275 -+#define COND_IGE 276 -+#define COND_ILE 277 -+#define COND_LPAR 278 -+#define COND_RPAR 279 -+#define COND_TILDA 280 -+#define COND_SS 281 -+#define COND_ISS 282 -+#define COND_ILHS 283 -+#define COND_IRHS 284 -+#define COND_LHS 285 -+#define COND_RHS 286 -+#define COND_PERCENT 287 -+#define COND_DOLLARS 288 -+#define COND_QUESTION 289 -+#define COND_AMPER 290 -+#define COND_EXCLAM 291 -+#define COND_IDENT 292 -+#define COND_NUMBER 293 -+#define COND_LITER 294 -+#define COND_ERROR 295 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 111 "cond.y" -+typedef union YYSTYPE { -+ struct cond_str str; -+ LPWSTR string; -+ INT value; -+} YYSTYPE; -+/* Line 1447 of yacc.c. */ -+#line 124 "cond.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ -Index: msi.rbuild -=================================================================== ---- msi.rbuild (revision 31639) -+++ msi.rbuild (working copy) -@@ -14,6 +14,7 @@ - appsearch.c - automation.c - classes.c -+ cond.tab.c - create.c - custom.c - database.c -@@ -40,6 +41,7 @@ - script.c - select.c - source.c -+ sql.tab.c - streams.c - string.c - suminfo.c -Index: msi_Ja.rc -=================================================================== ---- msi_Ja.rc (revision 31639) -+++ msi_Ja.rc (working copy) -@@ -0,0 +1,13 @@ -+LANGUAGE LANG_JAPANESE, SUBLANG_NEUTRAL -+ -+STRINGTABLE DISCARDABLE -+{ -+ 5 "pX %s ‚Ş‚Ý‚Â‚©‚č‚Ü‚ą‚ń‚Ĺ‚µ‚˝" -+ 9 "fBXN %s ‚đ‘}“ü‚µ‚Ä‚­‚ľ‚ł‚˘" -+ 10 "–łŚř‚Čp‰[^‚Ĺ‚·" -+ 11 "%s ‚Ě‚ ‚étH‹_‚đ“ü—Í‚µ‚Ä‚­‚ľ‚ł‚˘" -+ 12 "‹@”\\‚ĚC“Xg[‹Śł‚Ş‚ ‚č‚Ü‚ą‚ń" -+ 13 "‹@”\\‚Ş‚ ‚élbgŹ[N h‰Cu‚Ş‚ ‚č‚Ü‚ą‚ń" -+ 14 "‹@”\\‚̏ꏊ:" -+ 15 "%s ‚Ě‚ ‚étH‹_‚đ‘I‘đ‚µ‚Ä‚­‚ľ‚ł‚˘" -+} -Index: regsvr.c -=================================================================== ---- regsvr.c (revision 31639) -+++ regsvr.c (working copy) -@@ -40,6 +40,7 @@ - #include "msi.h" - #include "initguid.h" - #include "msipriv.h" -+#include "msiserver.h" - - WINE_DEFAULT_DEBUG_CHANNEL(msi); - -Index: sql.tab.c -=================================================================== ---- sql.tab.c (revision 31639) -+++ sql.tab.c (working copy) -@@ -0,0 +1,2579 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, or (at your option) -+ any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Written by Richard Stallman by simplifying the original so called -+ ``semantic'' parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Bison version. */ -+#define YYBISON_VERSION "2.1" -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 1 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 0 -+ -+/* Substitute the variable and function names. */ -+#define yyparse sql_parse -+#define yylex sql_lex -+#define yyerror sql_error -+#define yylval sql_lval -+#define yychar sql_char -+#define yydebug sql_debug -+#define yynerrs sql_nerrs -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ALTER = 258, -+ TK_AND = 259, -+ TK_BY = 260, -+ TK_CHAR = 261, -+ TK_COMMA = 262, -+ TK_CREATE = 263, -+ TK_DELETE = 264, -+ TK_DISTINCT = 265, -+ TK_DOT = 266, -+ TK_EQ = 267, -+ TK_FREE = 268, -+ TK_FROM = 269, -+ TK_GE = 270, -+ TK_GT = 271, -+ TK_HOLD = 272, -+ TK_ADD = 273, -+ TK_ID = 274, -+ TK_ILLEGAL = 275, -+ TK_INSERT = 276, -+ TK_INT = 277, -+ TK_INTEGER = 278, -+ TK_INTO = 279, -+ TK_IS = 280, -+ TK_KEY = 281, -+ TK_LE = 282, -+ TK_LONG = 283, -+ TK_LONGCHAR = 284, -+ TK_LP = 285, -+ TK_LT = 286, -+ TK_LOCALIZABLE = 287, -+ TK_MINUS = 288, -+ TK_NE = 289, -+ TK_NOT = 290, -+ TK_NULL = 291, -+ TK_OBJECT = 292, -+ TK_OR = 293, -+ TK_ORDER = 294, -+ TK_PRIMARY = 295, -+ TK_RP = 296, -+ TK_SELECT = 297, -+ TK_SET = 298, -+ TK_SHORT = 299, -+ TK_SPACE = 300, -+ TK_STAR = 301, -+ TK_STRING = 302, -+ TK_TABLE = 303, -+ TK_TEMPORARY = 304, -+ TK_UPDATE = 305, -+ TK_VALUES = 306, -+ TK_WHERE = 307, -+ TK_WILDCARD = 308, -+ COLUMN = 310, -+ FUNCTION = 311, -+ COMMENT = 312, -+ UNCLOSED_STRING = 313, -+ SPACE = 314, -+ ILLEGAL = 315, -+ END_OF_FILE = 316, -+ TK_LIKE = 317, -+ TK_NEGATION = 318 -+ }; -+#endif -+/* Tokens. */ -+#define TK_ALTER 258 -+#define TK_AND 259 -+#define TK_BY 260 -+#define TK_CHAR 261 -+#define TK_COMMA 262 -+#define TK_CREATE 263 -+#define TK_DELETE 264 -+#define TK_DISTINCT 265 -+#define TK_DOT 266 -+#define TK_EQ 267 -+#define TK_FREE 268 -+#define TK_FROM 269 -+#define TK_GE 270 -+#define TK_GT 271 -+#define TK_HOLD 272 -+#define TK_ADD 273 -+#define TK_ID 274 -+#define TK_ILLEGAL 275 -+#define TK_INSERT 276 -+#define TK_INT 277 -+#define TK_INTEGER 278 -+#define TK_INTO 279 -+#define TK_IS 280 -+#define TK_KEY 281 -+#define TK_LE 282 -+#define TK_LONG 283 -+#define TK_LONGCHAR 284 -+#define TK_LP 285 -+#define TK_LT 286 -+#define TK_LOCALIZABLE 287 -+#define TK_MINUS 288 -+#define TK_NE 289 -+#define TK_NOT 290 -+#define TK_NULL 291 -+#define TK_OBJECT 292 -+#define TK_OR 293 -+#define TK_ORDER 294 -+#define TK_PRIMARY 295 -+#define TK_RP 296 -+#define TK_SELECT 297 -+#define TK_SET 298 -+#define TK_SHORT 299 -+#define TK_SPACE 300 -+#define TK_STAR 301 -+#define TK_STRING 302 -+#define TK_TABLE 303 -+#define TK_TEMPORARY 304 -+#define TK_UPDATE 305 -+#define TK_VALUES 306 -+#define TK_WHERE 307 -+#define TK_WILDCARD 308 -+#define COLUMN 310 -+#define FUNCTION 311 -+#define COMMENT 312 -+#define UNCLOSED_STRING 313 -+#define SPACE 314 -+#define ILLEGAL 315 -+#define END_OF_FILE 316 -+#define TK_LIKE 317 -+#define TK_NEGATION 318 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 1 "sql.y" -+ -+ -+/* -+ * Implementation of the Microsoft Installer (msi.dll) -+ * -+ * Copyright 2002-2004 Mike McCormack for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "windef.h" -+#include "winbase.h" -+#include "query.h" -+#include "wine/list.h" -+#include "wine/debug.h" -+ -+#define YYLEX_PARAM info -+#define YYPARSE_PARAM info -+ -+static int sql_error(const char *str); -+ -+WINE_DEFAULT_DEBUG_CHANNEL(msi); -+ -+typedef struct tag_SQL_input -+{ -+ MSIDATABASE *db; -+ LPCWSTR command; -+ DWORD n, len; -+ MSIVIEW **view; /* view structure for the resulting query */ -+ struct list *mem; -+} SQL_input; -+ -+static LPWSTR SQL_getstring( void *info, const struct sql_str *str ); -+static INT SQL_getint( void *info ); -+static int sql_lex( void *SQL_lval, SQL_input *info ); -+ -+static LPWSTR parser_add_table( LPWSTR list, LPWSTR table ); -+static void *parser_alloc( void *info, unsigned int sz ); -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ); -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys); -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ); -+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op ); -+static struct expr * EXPR_column( void *info, const column_info *column ); -+static struct expr * EXPR_ival( void *info, int val ); -+static struct expr * EXPR_sval( void *info, const struct sql_str *str ); -+static struct expr * EXPR_wildcard( void *info ); -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 -+#endif -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 74 "sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 196 of yacc.c. */ -+#line 297 "sql.tab.c" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 219 of yacc.c. */ -+#line 309 "sql.tab.c" -+ -+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -+# define YYSIZE_T __SIZE_TYPE__ -+#endif -+#if ! defined (YYSIZE_T) && defined (size_t) -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+#endif -+#if ! defined (YYSIZE_T) -+# define YYSIZE_T unsigned int -+#endif -+ -+#ifndef YY_ -+# if YYENABLE_NLS -+# if ENABLE_NLS -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# endif -+# endif -+# ifndef YY_ -+# define YY_(msgid) msgid -+# endif -+#endif -+ -+#if ! defined (yyoverflow) || YYERROR_VERBOSE -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# else -+# define YYSTACK_ALLOC alloca -+# if defined (__STDC__) || defined (__cplusplus) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYINCLUDED_STDLIB_H -+# endif -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+# ifndef YYSTACK_ALLOC_MAXIMUM -+ /* The OS might guarantee only one guard page at the bottom of the stack, -+ and a page size can be as small as 4096 bytes. So we cannot safely -+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number -+ to allow for a few compiler-allocated temporary stack slots. */ -+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ -+# endif -+# else -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# ifndef YYSTACK_ALLOC_MAXIMUM -+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) -+# endif -+# ifdef __cplusplus -+extern "C" { -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifndef YYFREE -+# define YYFREE free -+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ -+ && (defined (__STDC__) || defined (__cplusplus))) -+void free (void *); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifdef __cplusplus -+} -+# endif -+# endif -+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ -+ -+ -+#if (! defined (yyoverflow) \ -+ && (! defined (__cplusplus) \ -+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ short int yyss; -+ YYSTYPE yyvs; -+ }; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined (__GNUC__) && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (0) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) -+ -+#endif -+ -+#if defined (__STDC__) || defined (__cplusplus) -+ typedef signed char yysigned_char; -+#else -+ typedef short int yysigned_char; -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 32 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 138 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 64 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 34 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 79 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 141 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 318 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const unsigned char yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -+ 55, 56, 57, 58, 59, 60, 61, 62, 63 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const unsigned short int yyprhs[] = -+{ -+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, -+ 28, 40, 47, 55, 62, 67, 70, 75, 81, 88, -+ 90, 92, 97, 101, 103, 106, 108, 111, 114, 116, -+ 120, 122, 127, 129, 131, 133, 135, 137, 139, 144, -+ 146, 149, 153, 156, 158, 162, 164, 166, 170, 173, -+ 176, 178, 182, 186, 190, 194, 198, 202, 206, 210, -+ 214, 218, 222, 227, 229, 231, 233, 237, 239, 243, -+ 247, 249, 252, 254, 256, 258, 262, 264, 266, 268 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yysigned_char yyrhs[] = -+{ -+ 65, 0, -1, 66, -1, 80, -1, 68, -1, 67, -+ -1, 69, -1, 70, -1, 71, -1, 21, 24, 95, -+ 30, 83, 41, 51, 30, 89, 41, -1, 21, 24, -+ 95, 30, 83, 41, 51, 30, 89, 41, 49, -1, -+ 8, 48, 95, 30, 73, 41, -1, 8, 48, 95, -+ 30, 73, 41, 17, -1, 50, 95, 43, 90, 52, -+ 87, -1, 50, 95, 43, 90, -1, 9, 84, -1, -+ 3, 48, 95, 72, -1, 3, 48, 95, 18, 75, -+ -1, 3, 48, 95, 18, 75, 17, -1, 17, -1, -+ 13, -1, 74, 40, 26, 83, -1, 74, 7, 75, -+ -1, 75, -1, 94, 76, -1, 77, -1, 77, 32, -+ -1, 77, 49, -1, 78, -1, 78, 35, 36, -1, -+ 6, -1, 6, 30, 79, 41, -1, 29, -1, 44, -+ -1, 22, -1, 28, -1, 37, -1, 97, -1, 81, -+ 39, 5, 83, -1, 81, -1, 42, 82, -1, 42, -+ 10, 82, -1, 83, 84, -1, 94, -1, 94, 7, -+ 83, -1, 46, -1, 85, -1, 85, 52, 87, -1, -+ 14, 95, -1, 14, 86, -1, 95, -1, 95, 7, -+ 86, -1, 30, 87, 41, -1, 87, 4, 87, -1, -+ 87, 38, 87, -1, 93, 12, 88, -1, 93, 16, -+ 88, -1, 93, 31, 88, -1, 93, 27, 88, -1, -+ 93, 15, 88, -1, 93, 34, 88, -1, 93, 25, -+ 36, -1, 93, 25, 35, 36, -1, 93, -1, 92, -+ -1, 92, -1, 92, 7, 89, -1, 91, -1, 91, -+ 7, 90, -1, 94, 12, 92, -1, 97, -1, 33, -+ 97, -1, 47, -1, 53, -1, 94, -1, 95, 11, -+ 96, -1, 96, -1, 96, -1, 19, -1, 23, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const unsigned short int yyrline[] = -+{ -+ 0, 124, 124, 132, 133, 134, 135, 136, 137, 141, -+ 151, 164, 176, 191, 201, 214, 227, 237, 247, 260, -+ 264, 271, 281, 291, 298, 307, 311, 315, 322, 326, -+ 333, 337, 341, 345, 349, 353, 357, 364, 373, 386, -+ 390, 394, 410, 431, 432, 436, 443, 444, 460, 470, -+ 483, 488, 497, 503, 509, 515, 521, 527, 533, 539, -+ 545, 551, 557, 566, 567, 571, 578, 589, 590, 598, -+ 606, 612, 618, 624, 633, 642, 648, 657, 664, 673 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "TK_ALTER", "TK_AND", "TK_BY", "TK_CHAR", -+ "TK_COMMA", "TK_CREATE", "TK_DELETE", "TK_DISTINCT", "TK_DOT", "TK_EQ", -+ "TK_FREE", "TK_FROM", "TK_GE", "TK_GT", "TK_HOLD", "TK_ADD", "TK_ID", -+ "TK_ILLEGAL", "TK_INSERT", "TK_INT", "TK_INTEGER", "TK_INTO", "TK_IS", -+ "TK_KEY", "TK_LE", "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LT", -+ "TK_LOCALIZABLE", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NULL", "TK_OBJECT", -+ "TK_OR", "TK_ORDER", "TK_PRIMARY", "TK_RP", "TK_SELECT", "TK_SET", -+ "TK_SHORT", "TK_SPACE", "TK_STAR", "TK_STRING", "TK_TABLE", -+ "TK_TEMPORARY", "TK_UPDATE", "TK_VALUES", "TK_WHERE", "TK_WILDCARD", -+ "AGG_FUNCTION.", "COLUMN", "FUNCTION", "COMMENT", "UNCLOSED_STRING", -+ "SPACE", "ILLEGAL", "END_OF_FILE", "TK_LIKE", "TK_NEGATION", "$accept", -+ "query", "onequery", "oneinsert", "onecreate", "oneupdate", "onedelete", -+ "onealter", "alterop", "table_def", "column_def", "column_and_type", -+ "column_type", "data_type_l", "data_type", "data_count", "oneselect", -+ "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", -+ "tablelist", "expr", "val", "constlist", "update_assign_list", -+ "column_assignment", "const_val", "column_val", "column", "table", "id", -+ "number", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const unsigned short int yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, -+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, -+ 315, 316, 317, 318 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const unsigned char yyr1[] = -+{ -+ 0, 64, 65, 66, 66, 66, 66, 66, 66, 67, -+ 67, 68, 68, 69, 69, 70, 71, 71, 71, 72, -+ 72, 73, 74, 74, 75, 76, 76, 76, 77, 77, -+ 78, 78, 78, 78, 78, 78, 78, 79, 80, 80, -+ 81, 81, 82, 83, 83, 83, 84, 84, 85, 85, -+ 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, -+ 87, 87, 87, 88, 88, 89, 89, 90, 90, 91, -+ 92, 92, 92, 92, 93, 94, 94, 95, 96, 97 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const unsigned char yyr2[] = -+{ -+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 10, -+ 11, 6, 7, 6, 4, 2, 4, 5, 6, 1, -+ 1, 4, 3, 1, 2, 1, 2, 2, 1, 3, -+ 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, -+ 2, 3, 2, 1, 3, 1, 1, 3, 2, 2, -+ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, -+ 3, 3, 4, 1, 1, 1, 3, 1, 3, 3, -+ 1, 2, 1, 1, 1, 3, 1, 1, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const unsigned char yydefact[] = -+{ -+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, -+ 4, 6, 7, 8, 3, 39, 0, 0, 0, 15, -+ 46, 0, 0, 78, 45, 40, 0, 43, 0, 76, -+ 0, 77, 1, 0, 0, 0, 49, 48, 0, 0, -+ 41, 42, 0, 0, 0, 0, 20, 19, 0, 16, -+ 0, 0, 0, 47, 0, 74, 0, 44, 75, 14, -+ 67, 0, 38, 17, 0, 0, 0, 23, 51, 50, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 18, 30, 34, 35, 32, 36, -+ 33, 24, 25, 28, 11, 0, 0, 52, 53, 54, -+ 79, 0, 72, 73, 55, 64, 63, 70, 59, 56, -+ 0, 61, 58, 57, 60, 0, 13, 68, 69, 0, -+ 26, 27, 0, 12, 22, 0, 71, 62, 0, 0, -+ 37, 29, 21, 0, 31, 0, 65, 9, 0, 10, -+ 66 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const short int yydefgoto[] = -+{ -+ -1, 7, 8, 9, 10, 11, 12, 13, 49, 65, -+ 66, 63, 91, 92, 93, 129, 14, 15, 25, 26, -+ 19, 20, 36, 53, 104, 135, 59, 60, 105, 106, -+ 55, 28, 29, 107 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -96 -+static const yysigned_char yypact[] = -+{ -+ 0, -43, -34, 4, 24, 1, 6, 19, -96, -96, -+ -96, -96, -96, -96, -96, 31, 6, 6, 6, -96, -+ 30, 6, 35, -96, -96, -96, 4, 67, 47, 65, -+ 42, -96, -96, 81, 101, 59, -96, 89, 48, 68, -+ -96, -96, 35, 6, 6, 35, -96, -96, 6, -96, -+ 6, 6, 48, 3, 76, -96, 35, -96, -96, 45, -+ 95, 93, -96, 98, 43, 75, 22, -96, -96, 89, -+ 18, 48, 48, 13, 13, 13, -23, 13, 13, 13, -+ 80, 48, 6, 46, -96, 87, -96, -96, -96, -96, -+ -96, -96, 51, 71, 105, 6, 97, -96, -96, 120, -+ -96, 102, -96, -96, -96, -96, -96, -96, -96, -96, -+ 90, -96, -96, -96, -96, 77, 3, -96, -96, 102, -+ -96, -96, 91, -96, -96, 35, -96, -96, 99, 92, -+ -96, -96, -96, 46, -96, 94, 123, 82, 46, -96, -+ -96 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yysigned_char yypgoto[] = -+{ -+ -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, -+ -96, -40, -96, -96, -96, -96, -96, -96, 110, -41, -+ 108, -96, 85, 23, 34, -1, 56, -96, -81, -8, -+ -5, 17, 10, -95 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -78 -+static const short int yytable[] = -+{ -+ 27, 57, 118, 1, 62, 16, 126, 71, 2, 3, -+ 67, 22, 110, 111, 17, 80, 31, 27, 18, 32, -+ 23, 4, 71, 30, 130, 23, 31, 31, 31, 95, -+ 54, 31, 23, 34, 35, 37, 100, 27, 39, 61, -+ 27, 72, 5, 64, 54, 64, 101, 24, 21, 85, -+ 6, 27, 136, 58, 23, 124, 72, 136, 43, 97, -+ 102, 31, 96, 54, 54, 86, 103, 23, 69, 100, -+ 33, 87, 88, 54, 42, 70, -77, 61, 52, 101, -+ 89, 24, 38, 120, 132, 44, 45, 90, 73, 50, -+ 64, 74, 75, 102, 98, 99, 51, 81, 56, 103, -+ 121, 76, 82, 77, 116, 83, 122, 78, 108, 109, -+ 79, 112, 113, 114, 46, 84, 94, 119, 47, 48, -+ 27, 115, 123, 125, 71, 100, 127, 131, 128, 133, -+ 138, 139, 40, 134, 41, 137, 68, 140, 117 -+}; -+ -+static const unsigned char yycheck[] = -+{ -+ 5, 42, 83, 3, 45, 48, 101, 4, 8, 9, -+ 50, 10, 35, 36, 48, 56, 6, 22, 14, 0, -+ 19, 21, 4, 6, 119, 19, 16, 17, 18, 7, -+ 38, 21, 19, 16, 17, 18, 23, 42, 21, 44, -+ 45, 38, 42, 48, 52, 50, 33, 46, 24, 6, -+ 50, 56, 133, 43, 19, 95, 38, 138, 11, 41, -+ 47, 51, 40, 71, 72, 22, 53, 19, 51, 23, -+ 39, 28, 29, 81, 7, 52, 11, 82, 30, 33, -+ 37, 46, 52, 32, 125, 43, 5, 44, 12, 30, -+ 95, 15, 16, 47, 71, 72, 7, 52, 30, 53, -+ 49, 25, 7, 27, 81, 12, 35, 31, 74, 75, -+ 34, 77, 78, 79, 13, 17, 41, 30, 17, 18, -+ 125, 41, 17, 26, 4, 23, 36, 36, 51, 30, -+ 7, 49, 22, 41, 26, 41, 51, 138, 82 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const unsigned char yystos[] = -+{ -+ 0, 3, 8, 9, 21, 42, 50, 65, 66, 67, -+ 68, 69, 70, 71, 80, 81, 48, 48, 14, 84, -+ 85, 24, 10, 19, 46, 82, 83, 94, 95, 96, -+ 95, 96, 0, 39, 95, 95, 86, 95, 52, 95, -+ 82, 84, 7, 11, 43, 5, 13, 17, 18, 72, -+ 30, 7, 30, 87, 93, 94, 30, 83, 96, 90, -+ 91, 94, 83, 75, 94, 73, 74, 75, 86, 95, -+ 87, 4, 38, 12, 15, 16, 25, 27, 31, 34, -+ 83, 52, 7, 12, 17, 6, 22, 28, 29, 37, -+ 44, 76, 77, 78, 41, 7, 40, 41, 87, 87, -+ 23, 33, 47, 53, 88, 92, 93, 97, 88, 88, -+ 35, 36, 88, 88, 88, 41, 87, 90, 92, 30, -+ 32, 49, 35, 17, 75, 26, 97, 36, 51, 79, -+ 97, 36, 83, 30, 41, 89, 92, 41, 7, 49, -+ 89 -+}; -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror (YY_("syntax error: cannot back up")); \ -+ YYERROR; \ -+ } \ -+while (0) -+ -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) -+#endif -+ -+ -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ -+ -+#ifndef YY_LOCATION_PRINT -+# if YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif -+ -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (&yylval, YYLEX_PARAM) -+#else -+# define YYLEX yylex (&yylval) -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yysymprint (stderr, \ -+ Type, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_stack_print (short int *bottom, short int *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ short int *bottom; -+ short int *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (/* Nothing. */; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yy_reduce_print (int yyrule) -+#else -+static void -+yy_reduce_print (yyrule) -+ int yyrule; -+#endif -+{ -+ int yyi; -+ unsigned long int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", -+ yyrule - 1, yylno); -+ /* Print the symbols being reduced, and their result. */ -+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) -+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); -+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (Rule); \ -+} while (0) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined (__GLIBC__) && defined (_STRING_H) -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+static YYSIZE_T -+# if defined (__STDC__) || defined (__cplusplus) -+yystrlen (const char *yystr) -+# else -+yystrlen (yystr) -+ const char *yystr; -+# endif -+{ -+ const char *yys = yystr; -+ -+ while (*yys++ != '\0') -+ continue; -+ -+ return yys - yystr - 1; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+static char * -+# if defined (__STDC__) || defined (__cplusplus) -+yystpcpy (char *yydest, const char *yysrc) -+# else -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+# endif -+{ -+ char *yyd = yydest; -+ const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+# ifndef yytnamerr -+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary -+ quotes and backslashes, so that it's suitable for yyerror. The -+ heuristic is that double-quoting is unnecessary unless the string -+ contains an apostrophe, a comma, or backslash (other than -+ backslash-backslash). YYSTR is taken from yytname. If YYRES is -+ null, do not copy; instead, return the length of what the result -+ would have been. */ -+static YYSIZE_T -+yytnamerr (char *yyres, const char *yystr) -+{ -+ if (*yystr == '"') -+ { -+ size_t yyn = 0; -+ char const *yyp = yystr; -+ -+ for (;;) -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } -+ do_not_strip_quotes: ; -+ } -+ -+ if (! yyres) -+ return yystrlen (yystr); -+ -+ return yystpcpy (yyres, yystr) - yyres; -+} -+# endif -+ -+#endif /* YYERROR_VERBOSE */ -+ -+ -+ -+#if YYDEBUG -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yysymprint (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ -+# ifdef YYPRINT -+ if (yytype < YYNTOKENS) -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# endif -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+#endif /* ! YYDEBUG */ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+#if defined (__STDC__) || defined (__cplusplus) -+static void -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ /* Pacify ``unused variable'' warnings. */ -+ (void) yyvaluep; -+ -+ if (!yymsg) -+ yymsg = "Deleting"; -+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM); -+# else -+int yyparse (); -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+# if defined (__STDC__) || defined (__cplusplus) -+int yyparse (void *YYPARSE_PARAM) -+# else -+int yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+# endif -+#else /* ! YYPARSE_PARAM */ -+#if defined (__STDC__) || defined (__cplusplus) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ ; -+#endif -+#endif -+{ -+ /* The look-ahead symbol. */ -+int yychar; -+ -+/* The semantic value of the look-ahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ int yystate; -+ int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Look-ahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ short int yyssa[YYINITDEPTH]; -+ short int *yyss = yyssa; -+ short int *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ YYSTYPE *yyvsp; -+ -+ -+ -+#define YYPOPSTACK (yyvsp--, yyssp--) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+ -+ /* When reducing, the number of symbols on the RHS of the reduced -+ rule. */ -+ int yylen; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. so pushing a state here evens the stacks. -+ */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ short int *yyss1 = yyss; -+ -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyexhaustedlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyexhaustedlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ short int *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+/* Do appropriate processing given the current state. */ -+/* Read a look-ahead token if we need one and don't already have one. */ -+/* yyresume: */ -+ -+ /* First try to decide what to do without reference to look-ahead token. */ -+ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a look-ahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Shift the look-ahead token. */ -+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -+ -+ /* Discard the token being shifted unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 125 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ *sql->view = (yyvsp[0].query); -+ ;} -+ break; -+ -+ case 9: -+#line 142 "sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ -+ INSERT_CreateView( sql->db, &insert, (yyvsp[-7].string), (yyvsp[-5].column_list), (yyvsp[-1].column_list), FALSE ); -+ if( !insert ) -+ YYABORT; -+ (yyval.query) = insert; -+ ;} -+ break; -+ -+ case 10: -+#line 152 "sql.y" -+ { -+ SQL_input *sql = (SQL_input*) info; -+ MSIVIEW *insert = NULL; -+ -+ INSERT_CreateView( sql->db, &insert, (yyvsp[-8].string), (yyvsp[-6].column_list), (yyvsp[-2].column_list), TRUE ); -+ if( !insert ) -+ YYABORT; -+ (yyval.query) = insert; -+ ;} -+ break; -+ -+ case 11: -+#line 165 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !(yyvsp[-1].column_list) ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, (yyvsp[-3].string), (yyvsp[-1].column_list), FALSE ); -+ if( !create ) -+ YYABORT; -+ (yyval.query) = create; -+ ;} -+ break; -+ -+ case 12: -+#line 177 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *create = NULL; -+ -+ if( !(yyvsp[-2].column_list) ) -+ YYABORT; -+ CREATE_CreateView( sql->db, &create, (yyvsp[-4].string), (yyvsp[-2].column_list), TRUE ); -+ if( !create ) -+ YYABORT; -+ (yyval.query) = create; -+ ;} -+ break; -+ -+ case 13: -+#line 192 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *update = NULL; -+ -+ UPDATE_CreateView( sql->db, &update, (yyvsp[-4].string), (yyvsp[-2].column_list), (yyvsp[0].expr) ); -+ if( !update ) -+ YYABORT; -+ (yyval.query) = update; -+ ;} -+ break; -+ -+ case 14: -+#line 202 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *update = NULL; -+ -+ UPDATE_CreateView( sql->db, &update, (yyvsp[-2].string), (yyvsp[0].column_list), NULL ); -+ if( !update ) -+ YYABORT; -+ (yyval.query) = update; -+ ;} -+ break; -+ -+ case 15: -+#line 215 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *delete = NULL; -+ -+ DELETE_CreateView( sql->db, &delete, (yyvsp[0].query) ); -+ if( !delete ) -+ YYABORT; -+ (yyval.query) = delete; -+ ;} -+ break; -+ -+ case 16: -+#line 228 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ MSIVIEW *alter = NULL; -+ -+ ALTER_CreateView( sql->db, &alter, (yyvsp[-1].string), NULL, (yyvsp[0].integer) ); -+ if( !alter ) -+ YYABORT; -+ (yyval.query) = alter; -+ ;} -+ break; -+ -+ case 17: -+#line 238 "sql.y" -+ { -+ SQL_input *sql = (SQL_input *)info; -+ MSIVIEW *alter = NULL; -+ -+ ALTER_CreateView( sql->db, &alter, (yyvsp[-2].string), (yyvsp[0].column_list), 0 ); -+ if (!alter) -+ YYABORT; -+ (yyval.query) = alter; -+ ;} -+ break; -+ -+ case 18: -+#line 248 "sql.y" -+ { -+ SQL_input *sql = (SQL_input *)info; -+ MSIVIEW *alter = NULL; -+ -+ ALTER_CreateView( sql->db, &alter, (yyvsp[-3].string), (yyvsp[-1].column_list), 1 ); -+ if (!alter) -+ YYABORT; -+ (yyval.query) = alter; -+ ;} -+ break; -+ -+ case 19: -+#line 261 "sql.y" -+ { -+ (yyval.integer) = 1; -+ ;} -+ break; -+ -+ case 20: -+#line 265 "sql.y" -+ { -+ (yyval.integer) = -1; -+ ;} -+ break; -+ -+ case 21: -+#line 272 "sql.y" -+ { -+ if( SQL_MarkPrimaryKeys( (yyvsp[-3].column_list), (yyvsp[0].column_list) ) ) -+ (yyval.column_list) = (yyvsp[-3].column_list); -+ else -+ (yyval.column_list) = NULL; -+ ;} -+ break; -+ -+ case 22: -+#line 282 "sql.y" -+ { -+ column_info *ci; -+ -+ for( ci = (yyvsp[-2].column_list); ci->next; ci = ci->next ) -+ ; -+ -+ ci->next = (yyvsp[0].column_list); -+ (yyval.column_list) = (yyvsp[-2].column_list); -+ ;} -+ break; -+ -+ case 23: -+#line 292 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 24: -+#line 299 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[-1].column_list); -+ (yyval.column_list)->type = ((yyvsp[0].column_type) | MSITYPE_VALID); -+ (yyval.column_list)->temporary = (yyvsp[0].column_type) & MSITYPE_TEMPORARY ? TRUE : FALSE; -+ ;} -+ break; -+ -+ case 25: -+#line 308 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[0].column_type); -+ ;} -+ break; -+ -+ case 26: -+#line 312 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_LOCALIZABLE; -+ ;} -+ break; -+ -+ case 27: -+#line 316 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_TEMPORARY; -+ ;} -+ break; -+ -+ case 28: -+#line 323 "sql.y" -+ { -+ (yyval.column_type) |= MSITYPE_NULLABLE; -+ ;} -+ break; -+ -+ case 29: -+#line 327 "sql.y" -+ { -+ (yyval.column_type) = (yyvsp[-2].column_type); -+ ;} -+ break; -+ -+ case 30: -+#line 334 "sql.y" -+ { -+ (yyval.column_type) = MSITYPE_STRING | 1; -+ ;} -+ break; -+ -+ case 31: -+#line 338 "sql.y" -+ { -+ (yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[-1].column_type); -+ ;} -+ break; -+ -+ case 32: -+#line 342 "sql.y" -+ { -+ (yyval.column_type) = 2; -+ ;} -+ break; -+ -+ case 33: -+#line 346 "sql.y" -+ { -+ (yyval.column_type) = 2; -+ ;} -+ break; -+ -+ case 34: -+#line 350 "sql.y" -+ { -+ (yyval.column_type) = 2; -+ ;} -+ break; -+ -+ case 35: -+#line 354 "sql.y" -+ { -+ (yyval.column_type) = 4; -+ ;} -+ break; -+ -+ case 36: -+#line 358 "sql.y" -+ { -+ (yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID; -+ ;} -+ break; -+ -+ case 37: -+#line 365 "sql.y" -+ { -+ if( ( (yyvsp[0].integer) > 255 ) || ( (yyvsp[0].integer) < 0 ) ) -+ YYABORT; -+ (yyval.column_type) = (yyvsp[0].integer); -+ ;} -+ break; -+ -+ case 38: -+#line 374 "sql.y" -+ { -+ UINT r; -+ -+ if( (yyvsp[0].column_list) ) -+ { -+ r = (yyvsp[-3].query)->ops->sort( (yyvsp[-3].query), (yyvsp[0].column_list) ); -+ if ( r != ERROR_SUCCESS) -+ YYABORT; -+ } -+ -+ (yyval.query) = (yyvsp[-3].query); -+ ;} -+ break; -+ -+ case 40: -+#line 391 "sql.y" -+ { -+ (yyval.query) = (yyvsp[0].query); -+ ;} -+ break; -+ -+ case 41: -+#line 395 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ r = DISTINCT_CreateView( sql->db, &(yyval.query), (yyvsp[0].query) ); -+ if (r != ERROR_SUCCESS) -+ { -+ (yyvsp[0].query)->ops->delete((yyvsp[0].query)); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 42: -+#line 411 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ if( (yyvsp[-1].column_list) ) -+ { -+ r = SELECT_CreateView( sql->db, &(yyval.query), (yyvsp[0].query), (yyvsp[-1].column_list) ); -+ if (r != ERROR_SUCCESS) -+ { -+ (yyvsp[0].query)->ops->delete((yyvsp[0].query)); -+ YYABORT; -+ } -+ } -+ else -+ (yyval.query) = (yyvsp[0].query); -+ ;} -+ break; -+ -+ case 44: -+#line 433 "sql.y" -+ { -+ (yyvsp[-2].column_list)->next = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 45: -+#line 437 "sql.y" -+ { -+ (yyval.column_list) = NULL; -+ ;} -+ break; -+ -+ case 47: -+#line 445 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ r = WHERE_CreateView( sql->db, &(yyval.query), (yyvsp[-2].query), (yyvsp[0].expr) ); -+ if( r != ERROR_SUCCESS ) -+ { -+ (yyvsp[-2].query)->ops->delete( (yyvsp[-2].query) ); -+ YYABORT; -+ } -+ ;} -+ break; -+ -+ case 48: -+#line 461 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ (yyval.query) = NULL; -+ r = TABLE_CreateView( sql->db, (yyvsp[0].string), &(yyval.query) ); -+ if( r != ERROR_SUCCESS || !(yyval.query) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 49: -+#line 471 "sql.y" -+ { -+ SQL_input* sql = (SQL_input*) info; -+ UINT r; -+ -+ r = JOIN_CreateView( sql->db, &(yyval.query), (yyvsp[0].string) ); -+ msi_free( (yyvsp[0].string) ); -+ if( r != ERROR_SUCCESS ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 50: -+#line 484 "sql.y" -+ { -+ (yyval.string) = strdupW((yyvsp[0].string)); -+ ;} -+ break; -+ -+ case 51: -+#line 489 "sql.y" -+ { -+ (yyval.string) = parser_add_table((yyvsp[0].string), (yyvsp[-2].string)); -+ if (!(yyval.string)) -+ YYABORT; -+ ;} -+ break; -+ -+ case 52: -+#line 498 "sql.y" -+ { -+ (yyval.expr) = (yyvsp[-1].expr); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 53: -+#line 504 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_AND, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 54: -+#line 510 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_OR, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 55: -+#line 516 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 56: -+#line 522 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 57: -+#line 528 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 58: -+#line 534 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 59: -+#line 540 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 60: -+#line 546 "sql.y" -+ { -+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 61: -+#line 552 "sql.y" -+ { -+ (yyval.expr) = EXPR_unary( info, (yyvsp[-2].expr), OP_ISNULL ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 62: -+#line 558 "sql.y" -+ { -+ (yyval.expr) = EXPR_unary( info, (yyvsp[-3].expr), OP_NOTNULL ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 65: -+#line 572 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, NULL, NULL ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ (yyval.column_list)->val = (yyvsp[0].expr); -+ ;} -+ break; -+ -+ case 66: -+#line 579 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, NULL, NULL ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ (yyval.column_list)->val = (yyvsp[-2].expr); -+ (yyval.column_list)->next = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 68: -+#line 591 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[-2].column_list); -+ (yyval.column_list)->next = (yyvsp[0].column_list); -+ ;} -+ break; -+ -+ case 69: -+#line 599 "sql.y" -+ { -+ (yyval.column_list) = (yyvsp[-2].column_list); -+ (yyval.column_list)->val = (yyvsp[0].expr); -+ ;} -+ break; -+ -+ case 70: -+#line 607 "sql.y" -+ { -+ (yyval.expr) = EXPR_ival( info, (yyvsp[0].integer) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 71: -+#line 613 "sql.y" -+ { -+ (yyval.expr) = EXPR_ival( info, -(yyvsp[0].integer) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 72: -+#line 619 "sql.y" -+ { -+ (yyval.expr) = EXPR_sval( info, &(yyvsp[0].str) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 73: -+#line 625 "sql.y" -+ { -+ (yyval.expr) = EXPR_wildcard( info ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 74: -+#line 634 "sql.y" -+ { -+ (yyval.expr) = EXPR_column( info, (yyvsp[0].column_list) ); -+ if( !(yyval.expr) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 75: -+#line 643 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, (yyvsp[-2].string), (yyvsp[0].string) ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 76: -+#line 649 "sql.y" -+ { -+ (yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[0].string) ); -+ if( !(yyval.column_list) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 77: -+#line 658 "sql.y" -+ { -+ (yyval.string) = (yyvsp[0].string); -+ ;} -+ break; -+ -+ case 78: -+#line 665 "sql.y" -+ { -+ (yyval.string) = SQL_getstring( info, &(yyvsp[0].str) ); -+ if( !(yyval.string) ) -+ YYABORT; -+ ;} -+ break; -+ -+ case 79: -+#line 674 "sql.y" -+ { -+ (yyval.integer) = SQL_getint( info ); -+ ;} -+ break; -+ -+ -+ default: break; -+ } -+ -+/* Line 1126 of yacc.c. */ -+#line 2080 "sql.tab.c" -+ -+ yyvsp -= yylen; -+ yyssp -= yylen; -+ -+ -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if YYERROR_VERBOSE -+ yyn = yypact[yystate]; -+ -+ if (YYPACT_NINF < yyn && yyn < YYLAST) -+ { -+ int yytype = YYTRANSLATE (yychar); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); -+ YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; -+ int yysize_overflow = 0; -+ char *yymsg = 0; -+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 -+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; -+ int yyx; -+ -+#if 0 -+ /* This is so xgettext sees the translatable formats that are -+ constructed on the fly. */ -+ YY_("syntax error, unexpected %s"); -+ YY_("syntax error, unexpected %s, expecting %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -+#endif -+ char *yyfmt; -+ char const *yyf; -+ static char const yyunexpected[] = "syntax error, unexpected %s"; -+ static char const yyexpecting[] = ", expecting %s"; -+ static char const yyor[] = " or %s"; -+ char yyformat[sizeof yyunexpected -+ + sizeof yyexpecting - 1 -+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) -+ * (sizeof yyor - 1))]; -+ char const *yyprefix = yyexpecting; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 1; -+ -+ yyarg[0] = yytname[yytype]; -+ yyfmt = yystpcpy (yyformat, yyunexpected); -+ -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) -+ { -+ yycount = 1; -+ yysize = yysize0; -+ yyformat[sizeof yyunexpected - 1] = '\0'; -+ break; -+ } -+ yyarg[yycount++] = yytname[yyx]; -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ yyfmt = yystpcpy (yyfmt, yyprefix); -+ yyprefix = yyor; -+ } -+ -+ yyf = YY_(yyformat); -+ yysize1 = yysize + yystrlen (yyf); -+ yysize_overflow |= yysize1 < yysize; -+ yysize = yysize1; -+ -+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) -+ yymsg = (char *) YYSTACK_ALLOC (yysize); -+ if (yymsg) -+ { -+ /* Avoid sprintf, as that infringes on the user's name space. -+ Don't have undefined behavior even if the translation -+ produced a string with the wrong number of "%s"s. */ -+ char *yyp = yymsg; -+ int yyi = 0; -+ while ((*yyp = *yyf)) -+ { -+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) -+ { -+ yyp += yytnamerr (yyp, yyarg[yyi++]); -+ yyf += 2; -+ } -+ else -+ { -+ yyp++; -+ yyf++; -+ } -+ } -+ yyerror (yymsg); -+ YYSTACK_FREE (yymsg); -+ } -+ else -+ { -+ yyerror (YY_("syntax error")); -+ goto yyexhaustedlab; -+ } -+ } -+ else -+#endif /* YYERROR_VERBOSE */ -+ yyerror (YY_("syntax error")); -+ } -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse look-ahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } -+ else -+ { -+ yydestruct ("Error: discarding", yytoken, &yylval); -+ yychar = YYEMPTY; -+ } -+ } -+ -+ /* Else will try to reuse look-ahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+ /* Pacify compilers like GCC when the user code never invokes -+ YYERROR and the label yyerrorlab therefore never appears in user -+ code. */ -+ if (0) -+ goto yyerrorlab; -+ -+yyvsp -= yylen; -+ yyssp -= yylen; -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ -+ yydestruct ("Error: popping", yystos[yystate], yyvsp); -+ YYPOPSTACK; -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ *++yyvsp = yylval; -+ -+ -+ /* Shift the error token. */ -+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*-------------------------------------------------. -+| yyexhaustedlab -- memory exhaustion comes here. | -+`-------------------------------------------------*/ -+yyexhaustedlab: -+ yyerror (YY_("memory exhausted")); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+ if (yychar != YYEOF && yychar != YYEMPTY) -+ yydestruct ("Cleanup: discarding lookahead", -+ yytoken, &yylval); -+ while (yyssp != yyss) -+ { -+ yydestruct ("Cleanup: popping", -+ yystos[*yyssp], yyvsp); -+ YYPOPSTACK; -+ } -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+ return yyresult; -+} -+ -+ -+#line 679 "sql.y" -+ -+ -+static LPWSTR parser_add_table(LPWSTR list, LPWSTR table) -+{ -+ DWORD size = lstrlenW(list) + lstrlenW(table) + 2; -+ static const WCHAR space[] = {' ',0}; -+ -+ list = msi_realloc(list, size * sizeof(WCHAR)); -+ if (!list) return NULL; -+ -+ lstrcatW(list, space); -+ lstrcatW(list, table); -+ return list; -+} -+ -+static void *parser_alloc( void *info, unsigned int sz ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ struct list *mem; -+ -+ mem = msi_alloc( sizeof (struct list) + sz ); -+ list_add_tail( sql->mem, mem ); -+ return &mem[1]; -+} -+ -+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column ) -+{ -+ column_info *col; -+ -+ col = parser_alloc( info, sizeof (*col) ); -+ if( col ) -+ { -+ col->table = table; -+ col->column = column; -+ col->val = NULL; -+ col->type = 0; -+ col->next = NULL; -+ } -+ -+ return col; -+} -+ -+static int sql_lex( void *SQL_lval, SQL_input *sql ) -+{ -+ int token; -+ struct sql_str * str = SQL_lval; -+ -+ do -+ { -+ sql->n += sql->len; -+ if( ! sql->command[sql->n] ) -+ return 0; /* end of input */ -+ -+ /* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */ -+ sql->len = sqliteGetToken( &sql->command[sql->n], &token ); -+ if( sql->len==0 ) -+ break; -+ str->data = &sql->command[sql->n]; -+ str->len = sql->len; -+ } -+ while( token == TK_SPACE ); -+ -+ /* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */ -+ -+ return token; -+} -+ -+LPWSTR SQL_getstring( void *info, const struct sql_str *strdata ) -+{ -+ LPCWSTR p = strdata->data; -+ UINT len = strdata->len; -+ LPWSTR str; -+ -+ /* if there's quotes, remove them */ -+ if( ( (p[0]=='`') && (p[len-1]=='`') ) || -+ ( (p[0]=='\'') && (p[len-1]=='\'') ) ) -+ { -+ p++; -+ len -= 2; -+ } -+ str = parser_alloc( info, (len + 1)*sizeof(WCHAR) ); -+ if( !str ) -+ return str; -+ memcpy( str, p, len*sizeof(WCHAR) ); -+ str[len]=0; -+ -+ return str; -+} -+ -+INT SQL_getint( void *info ) -+{ -+ SQL_input* sql = (SQL_input*) info; -+ LPCWSTR p = &sql->command[sql->n]; -+ INT i, r = 0; -+ -+ for( i=0; ilen; i++ ) -+ { -+ if( '0' > p[i] || '9' < p[i] ) -+ { -+ ERR("should only be numbers here!\n"); -+ break; -+ } -+ r = (p[i]-'0') + r*10; -+ } -+ -+ return r; -+} -+ -+static int sql_error( const char *str ) -+{ -+ return 0; -+} -+ -+static struct expr * EXPR_wildcard( void *info ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_WILDCARD; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COMPLEX; -+ e->u.expr.left = l; -+ e->u.expr.op = op; -+ e->u.expr.right = r; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_UNARY; -+ e->u.expr.left = l; -+ e->u.expr.op = op; -+ e->u.expr.right = NULL; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_column( void *info, const column_info *column ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_COLUMN; -+ e->u.sval = column->column; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_ival( void *info, int val ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_IVAL; -+ e->u.ival = val; -+ } -+ return e; -+} -+ -+static struct expr * EXPR_sval( void *info, const struct sql_str *str ) -+{ -+ struct expr *e = parser_alloc( info, sizeof *e ); -+ if( e ) -+ { -+ e->type = EXPR_SVAL; -+ e->u.sval = SQL_getstring( info, str ); -+ } -+ return e; -+} -+ -+static BOOL SQL_MarkPrimaryKeys( column_info *cols, -+ column_info *keys ) -+{ -+ column_info *k; -+ BOOL found = TRUE; -+ -+ for( k = keys; k && found; k = k->next ) -+ { -+ column_info *c; -+ -+ found = FALSE; -+ for( c = cols; c && !found; c = c->next ) -+ { -+ if( lstrcmpW( k->column, c->column ) ) -+ continue; -+ c->type |= MSITYPE_KEY; -+ found = TRUE; -+ } -+ } -+ -+ return found; -+} -+ -+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview, -+ struct list *mem ) -+{ -+ SQL_input sql; -+ int r; -+ -+ *phview = NULL; -+ -+ sql.db = db; -+ sql.command = command; -+ sql.n = 0; -+ sql.len = 0; -+ sql.view = phview; -+ sql.mem = mem; -+ -+ r = sql_parse(&sql); -+ -+ TRACE("Parse returned %d\n", r); -+ if( r ) -+ { -+ *sql.view = NULL; -+ return ERROR_BAD_QUERY_SYNTAX; -+ } -+ -+ return ERROR_SUCCESS; -+} -+ -Index: sql.tab.h -=================================================================== ---- sql.tab.h (revision 31639) -+++ sql.tab.h (working copy) -@@ -0,0 +1,180 @@ -+/* A Bison parser, made by GNU Bison 2.1. */ -+ -+/* Skeleton parser for Yacc-like parsing with Bison, -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, or (at your option) -+ any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, when this file is copied by Bison into a -+ Bison output file, you may use that output file without restriction. -+ This special exception was added by the Free Software Foundation -+ in version 1.24 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ TK_ALTER = 258, -+ TK_AND = 259, -+ TK_BY = 260, -+ TK_CHAR = 261, -+ TK_COMMA = 262, -+ TK_CREATE = 263, -+ TK_DELETE = 264, -+ TK_DISTINCT = 265, -+ TK_DOT = 266, -+ TK_EQ = 267, -+ TK_FREE = 268, -+ TK_FROM = 269, -+ TK_GE = 270, -+ TK_GT = 271, -+ TK_HOLD = 272, -+ TK_ADD = 273, -+ TK_ID = 274, -+ TK_ILLEGAL = 275, -+ TK_INSERT = 276, -+ TK_INT = 277, -+ TK_INTEGER = 278, -+ TK_INTO = 279, -+ TK_IS = 280, -+ TK_KEY = 281, -+ TK_LE = 282, -+ TK_LONG = 283, -+ TK_LONGCHAR = 284, -+ TK_LP = 285, -+ TK_LT = 286, -+ TK_LOCALIZABLE = 287, -+ TK_MINUS = 288, -+ TK_NE = 289, -+ TK_NOT = 290, -+ TK_NULL = 291, -+ TK_OBJECT = 292, -+ TK_OR = 293, -+ TK_ORDER = 294, -+ TK_PRIMARY = 295, -+ TK_RP = 296, -+ TK_SELECT = 297, -+ TK_SET = 298, -+ TK_SHORT = 299, -+ TK_SPACE = 300, -+ TK_STAR = 301, -+ TK_STRING = 302, -+ TK_TABLE = 303, -+ TK_TEMPORARY = 304, -+ TK_UPDATE = 305, -+ TK_VALUES = 306, -+ TK_WHERE = 307, -+ TK_WILDCARD = 308, -+ COLUMN = 310, -+ FUNCTION = 311, -+ COMMENT = 312, -+ UNCLOSED_STRING = 313, -+ SPACE = 314, -+ ILLEGAL = 315, -+ END_OF_FILE = 316, -+ TK_LIKE = 317, -+ TK_NEGATION = 318 -+ }; -+#endif -+/* Tokens. */ -+#define TK_ALTER 258 -+#define TK_AND 259 -+#define TK_BY 260 -+#define TK_CHAR 261 -+#define TK_COMMA 262 -+#define TK_CREATE 263 -+#define TK_DELETE 264 -+#define TK_DISTINCT 265 -+#define TK_DOT 266 -+#define TK_EQ 267 -+#define TK_FREE 268 -+#define TK_FROM 269 -+#define TK_GE 270 -+#define TK_GT 271 -+#define TK_HOLD 272 -+#define TK_ADD 273 -+#define TK_ID 274 -+#define TK_ILLEGAL 275 -+#define TK_INSERT 276 -+#define TK_INT 277 -+#define TK_INTEGER 278 -+#define TK_INTO 279 -+#define TK_IS 280 -+#define TK_KEY 281 -+#define TK_LE 282 -+#define TK_LONG 283 -+#define TK_LONGCHAR 284 -+#define TK_LP 285 -+#define TK_LT 286 -+#define TK_LOCALIZABLE 287 -+#define TK_MINUS 288 -+#define TK_NE 289 -+#define TK_NOT 290 -+#define TK_NULL 291 -+#define TK_OBJECT 292 -+#define TK_OR 293 -+#define TK_ORDER 294 -+#define TK_PRIMARY 295 -+#define TK_RP 296 -+#define TK_SELECT 297 -+#define TK_SET 298 -+#define TK_SHORT 299 -+#define TK_SPACE 300 -+#define TK_STAR 301 -+#define TK_STRING 302 -+#define TK_TABLE 303 -+#define TK_TEMPORARY 304 -+#define TK_UPDATE 305 -+#define TK_VALUES 306 -+#define TK_WHERE 307 -+#define TK_WILDCARD 308 -+#define COLUMN 310 -+#define FUNCTION 311 -+#define COMMENT 312 -+#define UNCLOSED_STRING 313 -+#define SPACE 314 -+#define ILLEGAL 315 -+#define END_OF_FILE 316 -+#define TK_LIKE 317 -+#define TK_NEGATION 318 -+ -+ -+ -+ -+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -+#line 74 "sql.y" -+typedef union YYSTYPE { -+ struct sql_str str; -+ LPWSTR string; -+ column_info *column_list; -+ MSIVIEW *query; -+ struct expr *expr; -+ USHORT column_type; -+ int integer; -+} YYSTYPE; -+/* Line 1447 of yacc.c. */ -+#line 172 "sql.tab.h" -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+ -+ -+ diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h index 0516dd18da7..cf9e6909f5d 100644 --- a/dll/win32/msi/msipriv.h +++ b/dll/win32/msi/msipriv.h @@ -143,13 +143,15 @@ typedef struct tagMSIMEDIAINFO LPWSTR volume_label; BOOL is_continuous; BOOL is_extracted; - WCHAR source[MAX_PATH]; + WCHAR sourcedir[MAX_PATH]; } MSIMEDIAINFO; typedef struct tagMSIPATCHINFO { + struct list entry; LPWSTR patchcode; LPWSTR transforms; + LPWSTR localfile; } MSIPATCHINFO; typedef struct _column_info @@ -302,7 +304,7 @@ typedef struct tagMSIPACKAGE { MSIOBJECTHDR hdr; MSIDATABASE *db; - MSIPATCHINFO *patch; + struct list patches; struct list components; struct list features; struct list files; @@ -466,6 +468,7 @@ typedef struct tagMSIFILE LPWSTR TargetPath; BOOL IsCompressed; MSIFILEHASHINFO hash; + UINT disk_id; } MSIFILE; typedef struct tagMSITEMPFILE @@ -553,6 +556,7 @@ struct tagMSIMIME struct list entry; LPWSTR ContentType; /* Primary Key */ MSIEXTENSION *Extension; + LPWSTR suffix; LPWSTR clsid; MSICLASS *Class; /* not in the table, set during installation */ @@ -660,8 +664,7 @@ enum StringPersistence StringNonPersistent = 1 }; -extern BOOL msi_addstringW( string_table *st, UINT string_no, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence ); - +extern BOOL msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcount, enum StringPersistence persistence ); extern UINT msi_string2idW( const string_table *st, LPCWSTR buffer, UINT *id ); extern VOID msi_destroy_stringtable( string_table *st ); extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id ); @@ -672,8 +675,6 @@ extern UINT msi_save_string_table( const string_table *st, IStorage *storage ); extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name ); extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table ); -extern UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname, - USHORT **pdata, UINT *psz ); extern UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table, BYTE **pdata, UINT *psz ); extern UINT write_stream_data( IStorage *stg, LPCWSTR stname, @@ -685,7 +686,10 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, LPCWSTR szTransformFile, int iErrorCond ); extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg ); +/* patch functions */ extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ); +extern UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ); +extern UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch ); /* action internals */ extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ); @@ -724,6 +728,7 @@ extern BOOL decode_streamname(LPCWSTR in, LPWSTR out); /* database internals */ extern UINT db_get_raw_stream( MSIDATABASE *, LPCWSTR, IStream ** ); +void db_destroy_stream( MSIDATABASE *, LPCWSTR ); extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** ); extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** ); extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... ); @@ -748,10 +753,7 @@ extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ); extern MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *, LPCWSTR ); extern UINT MSI_OpenPackageW( LPCWSTR szPackage, MSIPACKAGE **pPackage ); extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR ); -extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR ); extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD * ); -extern UINT MSI_GetPropertyW( MSIPACKAGE *, LPCWSTR, LPWSTR, LPDWORD ); -extern UINT MSI_GetPropertyA(MSIPACKAGE *, LPCSTR, LPSTR, LPDWORD ); extern MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *, LPCWSTR ); extern UINT MSI_GetComponentStateW( MSIPACKAGE *, LPCWSTR, INSTALLSTATE *, INSTALLSTATE * ); extern UINT MSI_GetFeatureStateW( MSIPACKAGE *, LPCWSTR, INSTALLSTATE *, INSTALLSTATE * ); @@ -760,6 +762,7 @@ extern UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ); extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR); extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR); extern UINT msi_clone_properties(MSIPACKAGE *); +extern UINT msi_set_context(MSIPACKAGE *); extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT); /* for deformating */ @@ -787,12 +790,15 @@ extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT d LPCWSTR szUserSid, HKEY *key, BOOL create); extern UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create); +extern UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, + HKEY *key, BOOL create); extern UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create); extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_DeleteProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct); +extern UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context); extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid); @@ -963,16 +969,23 @@ extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package); extern UINT ACTION_RegisterFonts(MSIPACKAGE *package); +extern UINT ACTION_UnregisterClassInfo(MSIPACKAGE *package); +extern UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package); extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package); +extern UINT ACTION_UnregisterMIMEInfo(MSIPACKAGE *package); +extern UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package); /* Helpers */ extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data ); extern LPWSTR msi_dup_record_field(MSIRECORD *row, INT index); -extern LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop); -extern int msi_get_property_int( MSIPACKAGE *package, LPCWSTR prop, int def ); +extern LPWSTR msi_dup_property( MSIDATABASE *db, LPCWSTR prop ); +extern UINT msi_set_property( MSIDATABASE *, LPCWSTR, LPCWSTR ); +extern UINT msi_get_property( MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD ); +extern int msi_get_property_int( MSIDATABASE *package, LPCWSTR prop, int def ); extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, BOOL set_prop, BOOL load_prop, MSIFOLDER **folder); extern LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file); +extern void msi_reset_folders( MSIPACKAGE *package, BOOL source ); extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component ); extern MSIFEATURE *get_loaded_feature( MSIPACKAGE* package, LPCWSTR Feature ); extern MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file ); @@ -992,6 +1005,7 @@ extern WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... ); extern UINT msi_create_component_directories( MSIPACKAGE *package ); extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value); +extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix); /* media */ @@ -1084,6 +1098,23 @@ static const WCHAR szHU[] = {'H','K','E','Y','_','U','S','E','R','S','\\',0}; static const WCHAR szWindowsFolder[] = {'W','i','n','d','o','w','s','F','o','l','d','e','r',0}; static const WCHAR szAppSearch[] = {'A','p','p','S','e','a','r','c','h',0}; static const WCHAR szMoveFiles[] = {'M','o','v','e','F','i','l','e','s',0}; +static const WCHAR szCCPSearch[] = {'C','C','P','S','e','a','r','c','h',0}; +static const WCHAR szUnregisterClassInfo[] = {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0}; +static const WCHAR szUnregisterExtensionInfo[] = {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0}; +static const WCHAR szUnregisterMIMEInfo[] = {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0}; +static const WCHAR szUnregisterProgIdInfo[] = {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0}; +static const WCHAR szRegisterFonts[] = {'R','e','g','i','s','t','e','r','F','o','n','t','s',0}; +static const WCHAR szUnregisterFonts[] = {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0}; +static const WCHAR szCLSID[] = {'C','L','S','I','D',0}; +static const WCHAR szProgID[] = {'P','r','o','g','I','D',0}; +static const WCHAR szVIProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0}; +static const WCHAR szAppID[] = {'A','p','p','I','D',0}; +static const WCHAR szDefaultIcon[] = {'D','e','f','a','u','l','t','I','c','o','n',0}; +static const WCHAR szInprocHandler[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r',0}; +static const WCHAR szInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; +static const WCHAR szMIMEDatabase[] = {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t',' ','T','y','p','e','\\',0}; +static const WCHAR szLocalPackage[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0}; +static const WCHAR szOriginalDatabase[] = {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; /* memory allocation macro functions */ static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1); diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c index b1741ae87cf..fba722fe55c 100644 --- a/dll/win32/msi/package.c +++ b/dll/win32/msi/package.c @@ -214,6 +214,7 @@ static void free_package_structures( MSIPACKAGE *package ) MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry ); list_remove( &mt->entry ); + msi_free( mt->suffix ); msi_free( mt->clsid ); msi_free( mt->ContentType ); msi_free( mt ); @@ -263,11 +264,15 @@ static void free_package_structures( MSIPACKAGE *package ) msi_free( package->script ); } - if (package->patch) + LIST_FOR_EACH_SAFE( item, cursor, &package->patches ) { - msi_free( package->patch->patchcode ); - msi_free( package->patch->transforms ); - msi_free( package->patch ); + MSIPATCHINFO *patch = LIST_ENTRY( item, MSIPATCHINFO, entry ); + + list_remove( &patch->entry ); + msi_free( patch->patchcode ); + msi_free( patch->transforms ); + msi_free( patch->localfile ); + msi_free( patch ); } msi_free( package->BaseURL ); @@ -388,7 +393,7 @@ static UINT set_installed_prop( MSIPACKAGE *package ) if (r == ERROR_SUCCESS) { RegCloseKey( hkey ); - MSI_SetPropertyW( package, szInstalled, szOne ); + msi_set_property( package->db, szInstalled, szOne ); } return r; @@ -431,7 +436,7 @@ static UINT set_user_sid_prop( MSIPACKAGE *package ) if (!ConvertSidToStringSidW( psid, &sid_str )) goto done; - r = MSI_SetPropertyW( package, szUserSID, sid_str ); + r = msi_set_property( package->db, szUserSID, sid_str ); done: LocalFree( sid_str ); @@ -563,7 +568,7 @@ static void set_msi_assembly_prop(MSIPACKAGE *package) if (!val_len || !verstr) goto done; - MSI_SetPropertyW(package, netasm, verstr); + msi_set_property(package->db, netasm, verstr); done: msi_free(fusion); @@ -689,96 +694,96 @@ static VOID set_installer_properties(MSIPACKAGE *package) SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, CFF, pth); + msi_set_property(package->db, CFF, pth); SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, PFF, pth); + msi_set_property(package->db, PFF, pth); SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, CADF, pth); + msi_set_property(package->db, CADF, pth); SHGetFolderPathW(NULL,CSIDL_FAVORITES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, FaF, pth); + msi_set_property(package->db, FaF, pth); SHGetFolderPathW(NULL,CSIDL_FONTS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, FoF, pth); + msi_set_property(package->db, FoF, pth); SHGetFolderPathW(NULL,CSIDL_SENDTO,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, SendTF, pth); + msi_set_property(package->db, SendTF, pth); SHGetFolderPathW(NULL,CSIDL_STARTMENU,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, SMF, pth); + msi_set_property(package->db, SMF, pth); SHGetFolderPathW(NULL,CSIDL_STARTUP,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, StF, pth); + msi_set_property(package->db, StF, pth); SHGetFolderPathW(NULL,CSIDL_TEMPLATES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, TemplF, pth); + msi_set_property(package->db, TemplF, pth); SHGetFolderPathW(NULL,CSIDL_DESKTOP,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, DF, pth); + msi_set_property(package->db, DF, pth); SHGetFolderPathW(NULL,CSIDL_PROGRAMS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, PMF, pth); + msi_set_property(package->db, PMF, pth); SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, ATF, pth); + msi_set_property(package->db, ATF, pth); SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, ADF, pth); + msi_set_property(package->db, ADF, pth); SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, SF, pth); - MSI_SetPropertyW(package, SF16, pth); + msi_set_property(package->db, SF, pth); + msi_set_property(package->db, SF16, pth); SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, LADF, pth); + msi_set_property(package->db, LADF, pth); SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, MPF, pth); + msi_set_property(package->db, MPF, pth); SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, PF, pth); + msi_set_property(package->db, PF, pth); SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth); strcatW(pth, szBackSlash); - MSI_SetPropertyW(package, WF, pth); + msi_set_property(package->db, WF, pth); /* Physical Memory is specified in MB. Using total amount. */ msex.dwLength = sizeof(msex); GlobalMemoryStatusEx( &msex ); sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys/1024/1024)); - MSI_SetPropertyW(package, szPhysicalMemory, bufstr); + msi_set_property(package->db, szPhysicalMemory, bufstr); SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth); ptr = strchrW(pth,'\\'); if (ptr) *(ptr+1) = 0; - MSI_SetPropertyW(package, WV, pth); + msi_set_property(package->db, WV, pth); GetTempPathW(MAX_PATH,pth); - MSI_SetPropertyW(package, TF, pth); + msi_set_property(package->db, TF, pth); /* in a wine environment the user is always admin and privileged */ - MSI_SetPropertyW(package,szAdminUser,szOne); - MSI_SetPropertyW(package,szPriv,szOne); + msi_set_property(package->db, szAdminUser, szOne); + msi_set_property(package->db, szPriv, szOne); /* set the os things */ OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); @@ -788,54 +793,54 @@ static VOID set_installer_properties(MSIPACKAGE *package) switch (OSVersion.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: - MSI_SetPropertyW(package,v9x,verstr); + msi_set_property(package->db, v9x, verstr); break; case VER_PLATFORM_WIN32_NT: - MSI_SetPropertyW(package,vNT,verstr); + msi_set_property(package->db, vNT, verstr); sprintfW(verstr,szFormat,OSVersion.wProductType); - MSI_SetPropertyW(package,szMsiNTProductType,verstr); + msi_set_property(package->db, szMsiNTProductType, verstr); break; } sprintfW(verstr,szFormat,OSVersion.dwBuildNumber); - MSI_SetPropertyW(package,szWinBuild,verstr); + msi_set_property(package->db, szWinBuild, verstr); /* just fudge this */ - MSI_SetPropertyW(package,szSPL,szSix); + msi_set_property(package->db, szSPL, szSix); sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION); - MSI_SetPropertyW( package, szVersionMsi, bufstr ); + msi_set_property( package->db, szVersionMsi, bufstr ); sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100); - MSI_SetPropertyW( package, szVersionDatabase, bufstr ); + msi_set_property( package->db, szVersionDatabase, bufstr ); GetSystemInfo( &sys_info ); if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel ); - MSI_SetPropertyW( package, szIntel, bufstr ); + msi_set_property( package->db, szIntel, bufstr ); } /* Screen properties. */ dc = GetDC(0); sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, HORZRES ) ); - MSI_SetPropertyW( package, szScreenX, bufstr ); + msi_set_property( package->db, szScreenX, bufstr ); sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, VERTRES )); - MSI_SetPropertyW( package, szScreenY, bufstr ); + msi_set_property( package->db, szScreenY, bufstr ); sprintfW( bufstr, szIntFormat, GetDeviceCaps( dc, BITSPIXEL )); - MSI_SetPropertyW( package, szColorBits, bufstr ); + msi_set_property( package->db, szColorBits, bufstr ); ReleaseDC(0, dc); /* USERNAME and COMPANYNAME */ - username = msi_dup_property( package, szUSERNAME ); - companyname = msi_dup_property( package, szCOMPANYNAME ); + username = msi_dup_property( package->db, szUSERNAME ); + companyname = msi_dup_property( package->db, szCOMPANYNAME ); if ((!username || !companyname) && RegOpenKeyW( HKEY_CURRENT_USER, szUserInfo, &hkey ) == ERROR_SUCCESS) { if (!username && (username = msi_reg_get_val_str( hkey, szDefName ))) - MSI_SetPropertyW( package, szUSERNAME, username ); + msi_set_property( package->db, szUSERNAME, username ); if (!companyname && (companyname = msi_reg_get_val_str( hkey, szDefCompany ))) - MSI_SetPropertyW( package, szCOMPANYNAME, companyname ); + msi_set_property( package->db, szCOMPANYNAME, companyname ); CloseHandle( hkey ); } if ((!username || !companyname) && @@ -843,10 +848,10 @@ static VOID set_installer_properties(MSIPACKAGE *package) { if (!username && (username = msi_reg_get_val_str( hkey, szRegisteredUser ))) - MSI_SetPropertyW( package, szUSERNAME, username ); + msi_set_property( package->db, szUSERNAME, username ); if (!companyname && (companyname = msi_reg_get_val_str( hkey, szRegisteredOrg ))) - MSI_SetPropertyW( package, szCOMPANYNAME, companyname ); + msi_set_property( package->db, szCOMPANYNAME, companyname ); CloseHandle( hkey ); } msi_free( username ); @@ -859,7 +864,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) GetSystemTime( &systemtime ); if (GetDateFormatW( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemtime, NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) - MSI_SetPropertyW( package, szDate, bufstr ); + msi_set_property( package->db, szDate, bufstr ); else ERR("Couldn't set Date property: GetDateFormat failed with error %d\n", GetLastError()); @@ -867,7 +872,7 @@ static VOID set_installer_properties(MSIPACKAGE *package) TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, &systemtime, NULL, bufstr, sizeof(bufstr)/sizeof(bufstr[0]) )) - MSI_SetPropertyW( package, szTime, bufstr ); + msi_set_property( package->db, szTime, bufstr ); else ERR("Couldn't set Time property: GetTimeFormat failed with error %d\n", GetLastError()); @@ -875,26 +880,24 @@ static VOID set_installer_properties(MSIPACKAGE *package) langid = GetUserDefaultLangID(); sprintfW(bufstr, szIntFormat, langid); - - MSI_SetPropertyW( package, szUserLangID, bufstr ); + msi_set_property( package->db, szUserLangID, bufstr ); langid = GetSystemDefaultLangID(); sprintfW(bufstr, szIntFormat, langid); - - MSI_SetPropertyW( package, szSystemLangID, bufstr ); + msi_set_property( package->db, szSystemLangID, bufstr ); sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode)); - MSI_SetPropertyW( package, szProductState, bufstr ); + msi_set_property( package->db, szProductState, bufstr ); len = 0; if (!GetUserNameW( NULL, &len ) && GetLastError() == ERROR_MORE_DATA) { WCHAR *username; - if ((username = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + if ((username = msi_alloc( len * sizeof(WCHAR) ))) { if (GetUserNameW( username, &len )) - MSI_SetPropertyW( package, szLogonUser, username ); - HeapFree( GetProcessHeap(), 0, username ); + msi_set_property( package->db, szLogonUser, username ); + msi_free( username ); } } } @@ -952,7 +955,7 @@ static UINT msi_load_summary_properties( MSIPACKAGE *package ) goto done; } - MSI_SetPropertyW( package, szPackageCode, package_code ); + msi_set_property( package->db, szPackageCode, package_code ); msi_free( package_code ); /* load package attributes */ @@ -988,6 +991,7 @@ static MSIPACKAGE *msi_alloc_package( void ) list_init( &package->RunningActions ); list_init( &package->sourcelist_info ); list_init( &package->sourcelist_media ); + list_init( &package->patches ); } return package; @@ -1013,10 +1017,10 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package) static void adjust_allusers_property( MSIPACKAGE *package ) { /* FIXME: this should depend on the user's privileges */ - if (msi_get_property_int( package, szAllUsers, 0 ) == 2) + if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2) { TRACE("resetting ALLUSERS property from 2 to 1\n"); - MSI_SetPropertyW( package, szAllUsers, szOne ); + msi_set_property( package->db, szAllUsers, szOne ); } } @@ -1043,12 +1047,14 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) create_temp_property_table( package ); msi_clone_properties( package ); - package->ProductCode = msi_dup_property( package, szProductCode ); + package->ProductCode = msi_dup_property( package->db, szProductCode ); + package->script = msi_alloc_zero( sizeof(MSISCRIPT) ); + set_installed_prop( package ); set_installer_properties( package ); sprintfW(uilevel,szpi,gUILevel); - MSI_SetPropertyW(package, szLevel, uilevel); + msi_set_property(package->db, szLevel, uilevel); r = msi_load_summary_properties( package ); if (r != ERROR_SUCCESS) @@ -1107,16 +1113,16 @@ UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ) GetUrlCacheEntryInfoW( szUrl, NULL, &size ); if ( GetLastError() != ERROR_FILE_NOT_FOUND ) { - cache_entry = HeapAlloc( GetProcessHeap(), 0, size ); + cache_entry = msi_alloc( size ); if ( !GetUrlCacheEntryInfoW( szUrl, cache_entry, &size ) ) { UINT error = GetLastError(); - HeapFree( GetProcessHeap(), 0, cache_entry ); + msi_free( cache_entry ); return error; } lstrcpyW( filename, cache_entry->lpszLocalFileName ); - HeapFree( GetProcessHeap(), 0, cache_entry ); + msi_free( cache_entry ); return ERROR_SUCCESS; } @@ -1130,12 +1136,12 @@ UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ) return ERROR_SUCCESS; } -static UINT msi_get_local_package_name( LPWSTR path ) +UINT msi_get_local_package_name( LPWSTR path, LPCWSTR suffix ) { static const WCHAR szInstaller[] = { '\\','I','n','s','t','a','l','l','e','r','\\',0}; - static const WCHAR fmt[] = { '%','x','.','m','s','i',0}; - DWORD time, len, i; + static const WCHAR fmt[] = {'%','x',0}; + DWORD time, len, i, offset; HANDLE handle; time = GetTickCount(); @@ -1146,7 +1152,8 @@ static UINT msi_get_local_package_name( LPWSTR path ) len = strlenW(path); for (i = 0; i < 0x10000; i++) { - snprintfW( &path[len], MAX_PATH - len, fmt, (time + i)&0xffff ); + offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff ); + memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) ); handle = CreateFileW( path, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); if (handle != INVALID_HANDLE_VALUE) @@ -1162,11 +1169,64 @@ static UINT msi_get_local_package_name( LPWSTR path ) return ERROR_SUCCESS; } +static UINT apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code ) +{ + UINT r; + DWORD len; + WCHAR patch_file[MAX_PATH]; + MSIDATABASE *patch_db; + MSIPATCHINFO *patch_info; + MSISUMMARYINFO *si; + + len = sizeof(patch_file) / sizeof(WCHAR); + r = MsiGetPatchInfoExW( patch_code, package->ProductCode, NULL, package->Context, + INSTALLPROPERTY_LOCALPACKAGEW, patch_file, &len ); + if (r != ERROR_SUCCESS) + { + ERR("failed to get patch filename %u\n", r); + return r; + } + + r = MSI_OpenDatabaseW( patch_file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db ); + if (r != ERROR_SUCCESS) + { + ERR("failed to open patch database %s\n", debugstr_w( patch_file )); + return r; + } + + si = MSI_GetSummaryInformationW( patch_db->storage, 0 ); + if (!si) + { + msiobj_release( &patch_db->hdr ); + return ERROR_FUNCTION_FAILED; + } + + r = msi_parse_patch_summary( si, &patch_info ); + msiobj_release( &si->hdr ); + if (r != ERROR_SUCCESS) + { + ERR("failed to parse patch summary %u\n", r); + msiobj_release( &patch_db->hdr ); + return r; + } + + r = msi_apply_patch_db( package, patch_db, patch_info ); + msiobj_release( &patch_db->hdr ); + if (r != ERROR_SUCCESS) + { + ERR("failed to apply patch %u\n", r); + msi_free( patch_info->patchcode ); + msi_free( patch_info->transforms ); + msi_free( patch_info->localfile ); + msi_free( patch_info ); + } + return r; +} + UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) { - static const WCHAR OriginalDatabase[] = - {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; static const WCHAR Database[] = {'D','A','T','A','B','A','S','E',0}; + static const WCHAR dotmsi[] = {'.','m','s','i',0}; MSIDATABASE *db = NULL; MSIPACKAGE *package; MSIHANDLE handle; @@ -1174,6 +1234,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) UINT r; WCHAR temppath[MAX_PATH], localfile[MAX_PATH], cachefile[MAX_PATH]; LPCWSTR file = szPackage; + DWORD index = 0; TRACE("%s %p\n", debugstr_w(szPackage), pPackage); @@ -1225,7 +1286,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) file = temppath; } - r = msi_get_local_package_name( localfile ); + r = msi_get_local_package_name( localfile, dotmsi ); if (r != ERROR_SUCCESS) return r; @@ -1273,23 +1334,44 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) if( file != szPackage ) track_tempfile( package, file ); - MSI_SetPropertyW( package, Database, db->path ); + msi_set_property( package->db, Database, db->path ); if( UrlIsW( szPackage, URLIS_URL ) ) - MSI_SetPropertyW( package, OriginalDatabase, szPackage ); + msi_set_property( package->db, szOriginalDatabase, szPackage ); else if( szPackage[0] == '#' ) - MSI_SetPropertyW( package, OriginalDatabase, db->path ); + msi_set_property( package->db, szOriginalDatabase, db->path ); else { WCHAR fullpath[MAX_PATH]; GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL ); - MSI_SetPropertyW( package, OriginalDatabase, fullpath ); + msi_set_property( package->db, szOriginalDatabase, fullpath ); } - package->script = msi_alloc_zero( sizeof(MSISCRIPT) ); - *pPackage = package; + msi_set_context( package ); + while (1) + { + WCHAR patch_code[GUID_SIZE]; + r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context, + MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL ); + if (r != ERROR_SUCCESS) + break; + + TRACE("found registered patch %s\n", debugstr_w(patch_code)); + + r = apply_registered_patch( package, patch_code ); + if (r != ERROR_SUCCESS) + { + ERR("registered patch failed to apply %u\n", r); + MSI_FreePackage( (MSIOBJECTHDR *)package ); + return r; + } + + index++; + } + + *pPackage = package; return ERROR_SUCCESS; } @@ -1357,6 +1439,7 @@ MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall) { MSIPACKAGE *package; MSIHANDLE handle = 0; + IUnknown *remote_unk; IWineMsiRemotePackage *remote_package; TRACE("(%d)\n",hInstall); @@ -1367,10 +1450,19 @@ MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall) handle = alloc_msihandle( &package->db->hdr ); msiobj_release( &package->hdr ); } - else if ((remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall ))) + else if ((remote_unk = msi_get_remote(hInstall))) { - IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle); - IWineMsiRemotePackage_Release(remote_package); + if (IUnknown_QueryInterface(remote_unk, &IID_IWineMsiRemotePackage, + (LPVOID *)&remote_package) == S_OK) + { + IWineMsiRemotePackage_GetActiveDatabase(remote_package, &handle); + IWineMsiRemotePackage_Release(remote_package); + } + else + { + WARN("remote handle %d is not a package\n", hInstall); + } + IUnknown_Release(remote_unk); } return handle; @@ -1621,7 +1713,7 @@ end: return r; } -static void msi_reset_folders( MSIPACKAGE *package, BOOL source ) +void msi_reset_folders( MSIPACKAGE *package, BOOL source ) { MSIFOLDER *folder; @@ -1640,7 +1732,7 @@ static void msi_reset_folders( MSIPACKAGE *package, BOOL source ) } } -UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) +UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue ) { MSIQUERY *view; MSIRECORD *row = NULL; @@ -1664,7 +1756,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) '`','_','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ', '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0}; - TRACE("%p %s %s\n", package, debugstr_w(szName), debugstr_w(szValue)); + TRACE("%p %s %s\n", db, debugstr_w(szName), debugstr_w(szValue)); if (!szName) return ERROR_INVALID_PARAMETER; @@ -1673,7 +1765,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) if (!szName[0]) return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS; - rc = MSI_GetPropertyW(package, szName, 0, &sz); + rc = msi_get_property(db, szName, 0, &sz); if (!szValue || !*szValue) { sprintfW(Query, Delete, szName); @@ -1694,7 +1786,7 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) MSI_RecordSetStringW(row, 2, szValue); } - rc = MSI_DatabaseOpenViewW(package->db, Query, &view); + rc = MSI_DatabaseOpenViewW(db, Query, &view); if (rc == ERROR_SUCCESS) { rc = MSI_ViewExecute(view, row); @@ -1705,9 +1797,6 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue) if (row) msiobj_release(&row->hdr); - if (rc == ERROR_SUCCESS && (!lstrcmpW(szName, cszSourceDir))) - msi_reset_folders(package, TRUE); - return rc; } @@ -1754,12 +1843,15 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue return ERROR_SUCCESS; } - ret = MSI_SetPropertyW( package, szName, szValue); + ret = msi_set_property( package->db, szName, szValue ); + if (ret == ERROR_SUCCESS && !strcmpW( szName, cszSourceDir )) + msi_reset_folders( package, TRUE ); + msiobj_release( &package->hdr ); return ret; } -static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name ) +static MSIRECORD *msi_get_property_row( MSIDATABASE *db, LPCWSTR name ) { MSIQUERY *view; MSIRECORD *rec, *row = NULL; @@ -1780,7 +1872,7 @@ static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name ) MSI_RecordSetStringW(rec, 1, name); - r = MSI_DatabaseOpenViewW(package->db, query, &view); + r = MSI_DatabaseOpenViewW(db, query, &view); if (r == ERROR_SUCCESS) { MSI_ViewExecute(view, rec); @@ -1794,13 +1886,13 @@ static MSIRECORD *MSI_GetPropertyRow( MSIPACKAGE *package, LPCWSTR name ) } /* internal function, not compatible with MsiGetPropertyW */ -UINT MSI_GetPropertyW( MSIPACKAGE *package, LPCWSTR szName, +UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName, LPWSTR szValueBuf, LPDWORD pchValueBuf ) { MSIRECORD *row; UINT rc = ERROR_FUNCTION_FAILED; - row = MSI_GetPropertyRow( package, szName ); + row = msi_get_property_row( db, szName ); if (*pchValueBuf > 0) szValueBuf[0] = 0; @@ -1826,19 +1918,19 @@ UINT MSI_GetPropertyW( MSIPACKAGE *package, LPCWSTR szName, return rc; } -LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop) +LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) { DWORD sz = 0; LPWSTR str; UINT r; - r = MSI_GetPropertyW(package, prop, NULL, &sz); + r = msi_get_property(db, prop, NULL, &sz); if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA) return NULL; sz++; str = msi_alloc(sz * sizeof(WCHAR)); - r = MSI_GetPropertyW(package, prop, str, &sz); + r = msi_get_property(db, prop, str, &sz); if (r != ERROR_SUCCESS) { msi_free(str); @@ -1848,9 +1940,9 @@ LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop) return str; } -int msi_get_property_int(MSIPACKAGE *package, LPCWSTR prop, int def) +int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def ) { - LPWSTR str = msi_dup_property(package, prop); + LPWSTR str = msi_dup_property( db, prop ); int val = str ? atoiW(str) : def; msi_free(str); return val; @@ -1929,7 +2021,7 @@ done: return r; } - row = MSI_GetPropertyRow( package, name ); + row = msi_get_property_row( package->db, name ); if (row) val = MSI_RecordGetString( row, 1 ); diff --git a/dll/win32/msi/registry.c b/dll/win32/msi/registry.c index 1cbdcc95288..518303f5da0 100644 --- a/dll/win32/msi/registry.c +++ b/dll/win32/msi/registry.c @@ -183,6 +183,16 @@ static const WCHAR szUserDataPatch_fmt[] = { 'U','s','e','r','D','a','t','a','\\', '%','s','\\','P','a','t','c','h','e','s','\\','%','s',0}; +static const WCHAR szUserDataProductPatches_fmt[] = { +'S','o','f','t','w','a','r','e','\\', +'M','i','c','r','o','s','o','f','t','\\', +'W','i','n','d','o','w','s','\\', +'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', +'I','n','s','t','a','l','l','e','r','\\', +'U','s','e','r','D','a','t','a','\\', +'%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\', +'P','a','t','c','h','e','s',0}; + static const WCHAR szInstallProperties_fmt[] = { 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', @@ -286,7 +296,7 @@ BOOL squash_guid(LPCWSTR in, LPWSTR out) out[0] = 0; - if (FAILED(CLSIDFromString((LPOLESTR)in, &guid))) + if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid))) return FALSE; for(i=0; i<8; i++) @@ -887,6 +897,69 @@ UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); } +UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context) +{ + UINT r; + WCHAR squished_patch[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + + TRACE("%s\n", debugstr_w(patch)); + if (!squash_guid(patch, squished_patch)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_patch)); + + if (context == MSIINSTALLCONTEXT_MACHINE) + sprintfW(keypath, szUserDataPatch_fmt, szLocalSid, squished_patch); + else + { + r = get_user_sid(&usersid); + if (r != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", r); + return r; + } + + sprintfW(keypath, szUserDataPatch_fmt, usersid, squished_patch); + LocalFree(usersid); + } + + return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath); +} + +UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, + HKEY *key, BOOL create) +{ + UINT rc; + WCHAR squished_product[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + + TRACE("%s\n", debugstr_w(product)); + if (!squash_guid(product, squished_product)) + return ERROR_FUNCTION_FAILED; + + if (context == MSIINSTALLCONTEXT_MACHINE) + sprintfW(keypath, szUserDataProductPatches_fmt, szLocalSid, squished_product); + else + { + rc = get_user_sid(&usersid); + if (rc != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", rc); + return rc; + } + + sprintfW(keypath, szUserDataProductPatches_fmt, usersid, squished_product); + LocalFree(usersid); + } + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create) { @@ -1156,7 +1229,7 @@ UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct, len = ( &p[21] - szDescriptor ); TRACE("length = %d\n", len); - *pUsed = len; + if (pUsed) *pUsed = len; return ERROR_SUCCESS; } @@ -1236,17 +1309,13 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) if (index && index - last_index != 1) return ERROR_INVALID_PARAMETER; + key = 0; r = RegCreateKeyW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesProd, &key); - if( r != ERROR_SUCCESS ) - return ERROR_NO_MORE_ITEMS; + if( r != ERROR_SUCCESS ) goto failed; r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &machine_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if( r != ERROR_SUCCESS ) - { - RegCloseKey(key); - return ERROR_NO_MORE_ITEMS; - } + if( r != ERROR_SUCCESS ) goto failed; if (machine_count && index <= machine_count) { @@ -1261,26 +1330,23 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) } RegCloseKey(key); + key = 0; r = get_user_sid(&usersid); if (r != ERROR_SUCCESS || !usersid) { ERR("Failed to retrieve user SID: %d\n", r); + last_index = 0; return r; } sprintfW(keypath, szInstaller_LocalManaged_fmt, usersid); LocalFree(usersid); r = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, &key); - if( r != ERROR_SUCCESS ) - return ERROR_NO_MORE_ITEMS; + if( r != ERROR_SUCCESS ) goto failed; r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &managed_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if( r != ERROR_SUCCESS ) - { - RegCloseKey(key); - return ERROR_NO_MORE_ITEMS; - } + if( r != ERROR_SUCCESS ) goto failed; if (managed_count && index <= machine_count + managed_count) { @@ -1295,17 +1361,13 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) } RegCloseKey(key); + key = 0; r = RegCreateKeyW(HKEY_CURRENT_USER, szUserProduct, &key); - if( r != ERROR_SUCCESS ) - return ERROR_NO_MORE_ITEMS; + if( r != ERROR_SUCCESS ) goto failed; r = RegQueryInfoKeyW(key, NULL, NULL, NULL, &unmanaged_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if( r != ERROR_SUCCESS ) - { - RegCloseKey(key); - return ERROR_NO_MORE_ITEMS; - } + if( r != ERROR_SUCCESS ) goto failed; if (unmanaged_count && index <= machine_count + managed_count + unmanaged_count) { @@ -1318,8 +1380,9 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid) return ERROR_SUCCESS; } } +failed: RegCloseKey(key); - + last_index = 0; return ERROR_NO_MORE_ITEMS; } @@ -2051,7 +2114,7 @@ UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid, DWORD idx = 0; UINT r; - static int last_index = 0; + static DWORD last_index; TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n", debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext, dwFilter, @@ -2087,6 +2150,8 @@ UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid, if (r == ERROR_SUCCESS) last_index = dwIndex; + else + last_index = 0; return r; } diff --git a/dll/win32/msi/script.c b/dll/win32/msi/script.c index 8dfa6d2ac05..4f223daa8b0 100644 --- a/dll/win32/msi/script.c +++ b/dll/win32/msi/script.c @@ -62,7 +62,7 @@ static HRESULT create_ActiveScriptSite(IUnknown *pUnkOuter, LPVOID *ppObj) if( pUnkOuter ) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MsiActiveScriptSite)); + object = msi_alloc_zero( sizeof(MsiActiveScriptSite) ); object->lpVtbl.lpVtbl = &ASS_Vtbl; object->ref = 1; @@ -236,7 +236,7 @@ static ULONG WINAPI MsiActiveScriptSite_Release(IActiveScriptSite* iface) TRACE("(%p/%p)\n", iface, This); if (!ref) - HeapFree(GetProcessHeap(), 0, This); + msi_free(This); return ref; } diff --git a/dll/win32/msi/storages.c b/dll/win32/msi/storages.c index 6a8134b5627..3e8887437a7 100644 --- a/dll/win32/msi/storages.c +++ b/dll/win32/msi/storages.c @@ -43,7 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct tabSTORAGE { UINT str_index; - LPWSTR name; IStorage *storage; } STORAGE; @@ -70,7 +69,7 @@ static BOOL storages_set_table_size(MSISTORAGESVIEW *sv, UINT size) return TRUE; } -static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPWSTR name, IStorage *stg) +static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPCWSTR name, IStorage *stg) { STORAGE *storage; @@ -78,14 +77,7 @@ static STORAGE *create_storage(MSISTORAGESVIEW *sv, LPWSTR name, IStorage *stg) if (!storage) return NULL; - storage->name = strdupW(name); - if (!storage->name) - { - msi_free(storage); - return NULL; - } - - storage->str_index = msi_addstringW(sv->db->strings, 0, storage->name, -1, 1, StringNonPersistent); + storage->str_index = msi_addstringW(sv->db->strings, name, -1, 1, StringNonPersistent); storage->storage = stg; if (storage->storage) @@ -436,8 +428,6 @@ static UINT STORAGES_delete(struct tagMSIVIEW *view) { if (sv->storages[i]->storage) IStorage_Release(sv->storages[i]->storage); - - msi_free(sv->storages[i]->name); msi_free(sv->storages[i]); } diff --git a/dll/win32/msi/streams.c b/dll/win32/msi/streams.c index 66bda767a00..59e845df82d 100644 --- a/dll/win32/msi/streams.c +++ b/dll/win32/msi/streams.c @@ -68,7 +68,7 @@ static BOOL streams_set_table_size(MSISTREAMSVIEW *sv, UINT size) return TRUE; } -static STREAM *create_stream(MSISTREAMSVIEW *sv, LPWSTR name, BOOL encoded, IStream *stm) +static STREAM *create_stream(MSISTREAMSVIEW *sv, LPCWSTR name, BOOL encoded, IStream *stm) { STREAM *stream; WCHAR decoded[MAX_STREAM_NAME_LEN]; @@ -84,7 +84,7 @@ static STREAM *create_stream(MSISTREAMSVIEW *sv, LPWSTR name, BOOL encoded, IStr name = decoded; } - stream->str_index = msi_addstringW(sv->db->strings, 0, name, -1, 1, StringNonPersistent); + stream->str_index = msi_addstringW(sv->db->strings, name, -1, 1, StringNonPersistent); stream->stream = stm; return stream; } @@ -183,7 +183,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U } encname = encode_streamname(FALSE, name); - IStorage_DestroyElement(sv->db->storage, encname); + db_destroy_stream(sv->db, encname); r = write_stream_data(sv->db->storage, name, data, count, FALSE); if (r != ERROR_SUCCESS) diff --git a/dll/win32/msi/string.c b/dll/win32/msi/string.c index 3bdc4360bd0..21b1db2a405 100644 --- a/dll/win32/msi/string.c +++ b/dll/win32/msi/string.c @@ -44,8 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct _msistring { - UINT persistent_refcount; - UINT nonpersistent_refcount; + USHORT persistent_refcount; + USHORT nonpersistent_refcount; LPWSTR str; } msistring; @@ -188,7 +188,7 @@ static void insert_string_sorted( string_table *st, UINT string_id ) st->sortcount++; } -static void set_st_entry( string_table *st, UINT n, LPWSTR str, UINT refcount, enum StringPersistence persistence ) +static void set_st_entry( string_table *st, UINT n, LPWSTR str, USHORT refcount, enum StringPersistence persistence ) { if (persistence == StringPersistent) { @@ -237,7 +237,7 @@ static UINT msi_string2idA( const string_table *st, LPCSTR buffer, UINT *id ) return r; } -static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT refcount, enum StringPersistence persistence ) +static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, USHORT refcount, enum StringPersistence persistence ) { LPWSTR str; int sz; @@ -288,42 +288,28 @@ static int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, U return n; } -int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence ) +int msi_addstringW( string_table *st, const WCHAR *data, int len, USHORT refcount, enum StringPersistence persistence ) { + UINT n; LPWSTR str; - /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */ - if( !data ) return 0; if( !data[0] ) return 0; - if( n > 0 ) + + if( msi_string2idW( st, data, &n ) == ERROR_SUCCESS ) { - if( st->strings[n].persistent_refcount || - st->strings[n].nonpersistent_refcount ) - return -1; - } - else - { - if( ERROR_SUCCESS == msi_string2idW( st, data, &n ) ) - { - if (persistence == StringPersistent) - st->strings[n].persistent_refcount += refcount; - else - st->strings[n].nonpersistent_refcount += refcount; - return n; - } - n = st_find_free_entry( st ); - if( n == -1 ) - return -1; + if (persistence == StringPersistent) + st->strings[n].persistent_refcount += refcount; + else + st->strings[n].nonpersistent_refcount += refcount; + return n; } - if( n < 1 ) - { - ERR("invalid index adding %s (%d)\n", debugstr_w( data ), n ); + n = st_find_free_entry( st ); + if( n == -1 ) return -1; - } /* allocate a new string */ if(len<0) diff --git a/dll/win32/msi/table.c b/dll/win32/msi/table.c index 6737ac59168..3b117ae53c4 100644 --- a/dll/win32/msi/table.c +++ b/dll/win32/msi/table.c @@ -1383,7 +1383,7 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI if ( r != ERROR_SUCCESS ) { LPCWSTR sval = MSI_RecordGetString( rec, i + 1 ); - val = msi_addstringW( tv->db->strings, 0, sval, -1, 1, + val = msi_addstringW( tv->db->strings, sval, -1, 1, persistent ? StringPersistent : StringNonPersistent ); } diff --git a/dll/win32/msi/upgrade.c b/dll/win32/msi/upgrade.c index a440070a4d8..b131d666fe2 100644 --- a/dll/win32/msi/upgrade.c +++ b/dll/win32/msi/upgrade.c @@ -61,8 +61,9 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, LPWSTR prop; LPWSTR newprop; DWORD len; + UINT r; - prop = msi_dup_property(package, action_property ); + prop = msi_dup_property(package->db, action_property ); if (prop) len = strlenW(prop); else @@ -87,9 +88,13 @@ static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property, newprop[0] = 0; strcatW(newprop,productid); - MSI_SetPropertyW(package, action_property, newprop); - TRACE("Found Related Product... %s now %s\n",debugstr_w(action_property), - debugstr_w(newprop)); + r = msi_set_property( package->db, action_property, newprop ); + if (r == ERROR_SUCCESS && !strcmpW( action_property, cszSourceDir )) + msi_reset_folders( package, TRUE ); + + TRACE("Found Related Product... %s now %s\n", + debugstr_w(action_property), debugstr_w(newprop)); + msi_free( prop ); msi_free( newprop ); } @@ -146,26 +151,30 @@ static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param) (LPBYTE)&check, &sz); /* check min */ ver = MSI_RecordGetString(rec,2); - comp_ver = msi_version_str_to_dword(ver); - r = check - comp_ver; - if (r < 0 || (r == 0 && !(attributes & - msidbUpgradeAttributesVersionMinInclusive))) + if (ver) { - RegCloseKey(hukey); - index ++; - continue; + comp_ver = msi_version_str_to_dword(ver); + r = check - comp_ver; + if (r < 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMinInclusive))) + { + RegCloseKey(hukey); + index ++; + continue; + } } /* check max */ ver = MSI_RecordGetString(rec,3); - comp_ver = msi_version_str_to_dword(ver); - r = check - comp_ver; - if (r > 0 || (r == 0 && !(attributes & - msidbUpgradeAttributesVersionMaxInclusive))) + if (ver) { - RegCloseKey(hukey); - index ++; - continue; + comp_ver = msi_version_str_to_dword(ver); + r = check - comp_ver; + if (r > 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMaxInclusive))) + { + RegCloseKey(hukey); + index ++; + continue; + } } /* check language*/ @@ -203,19 +212,19 @@ UINT ACTION_FindRelatedProducts(MSIPACKAGE *package) UINT rc = ERROR_SUCCESS; MSIQUERY *view; - if (msi_get_property_int(package, szInstalled, 0)) + if (msi_get_property_int(package->db, szInstalled, 0)) { TRACE("Skipping FindRelatedProducts action: product already installed\n"); return ERROR_SUCCESS; } - if (check_unique_action(package,szFindRelatedProducts)) + if (check_unique_action(package, szFindRelatedProducts)) { - TRACE("Skipping FindRelatedProducts action: already done on client side\n"); + TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n"); return ERROR_SUCCESS; } else - register_unique_action(package,szFindRelatedProducts); + register_unique_action(package, szFindRelatedProducts); rc = MSI_DatabaseOpenViewW(package->db, Query, &view); if (rc != ERROR_SUCCESS) diff --git a/dll/win32/msrle32/msrle32.rbuild b/dll/win32/msrle32/msrle32.rbuild index 6ef26447334..2b8a6ca4dc6 100644 --- a/dll/win32/msrle32/msrle32.rbuild +++ b/dll/win32/msrle32/msrle32.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/dll/win32/msxml3/domdoc.c b/dll/win32/msxml3/domdoc.c index aae8a343500..d72d20be8dc 100644 --- a/dll/win32/msxml3/domdoc.c +++ b/dll/win32/msxml3/domdoc.c @@ -2177,8 +2177,7 @@ xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk ) return S_OK; } - if ( punk ) - IUnknown_AddRef( punk ); + IUnknown_AddRef( punk ); if(This->site) IUnknown_Release( This->site ); diff --git a/dll/win32/msxml3/regsvr.c b/dll/win32/msxml3/regsvr.c index d9b47dde89b..415e5af613a 100644 --- a/dll/win32/msxml3/regsvr.c +++ b/dll/win32/msxml3/regsvr.c @@ -515,8 +515,23 @@ static struct regsvr_coclass const coclass_list[] = { "Both", "Microsoft.FreeThreadedXMLDOM.1.0", "1.0" + }, + { &CLSID_FreeThreadedDOMDocument26, + "Free Threaded XML DOM Document 2.6", + NULL, + "msxml3.dll", + "Both", + "Microsoft.FreeThreadedXMLDOM.1.0", + "1.0" + }, + { &CLSID_FreeThreadedDOMDocument30, + "Free Threaded XML DOM Document 3.0", + NULL, + "msxml3.dll", + "Both", + "Microsoft.FreeThreadedDOMDocument.1.0", + "1.0" }, - { &CLSID_XMLHTTPRequest, "XML HTTP Request", NULL, @@ -548,6 +563,14 @@ static struct regsvr_coclass const coclass_list[] = { "Msxml2.XMLSchemaCache", "3.0" }, + { &CLSID_XMLSchemaCache26, + "XML Schema Cache 2.6", + NULL, + "msxml3.dll", + "Both", + "Msxml2.XMLSchemaCache", + "2.6" + }, { &CLSID_XMLSchemaCache30, "XML Schema Cache 3.0", NULL, @@ -588,6 +611,22 @@ static struct regsvr_coclass const coclass_list[] = { "Msxml2.MXXMLWriter", "3.0" }, + { &CLSID_SAXAttributes, + "SAX Attribute", + NULL, + "msxml3.dll", + "Both", + "Msxml2.SAXAttributes", + NULL + }, + { &CLSID_SAXAttributes30, + "SAX Attribute 3.0", + NULL, + "msxml3.dll", + "Both", + "Msxml2.SAXAttributes", + "3.0" + }, { NULL } /* list terminator */ }; @@ -642,6 +681,16 @@ static struct progid const progid_list[] = { &CLSID_DOMFreeThreadedDocument, "Microsoft.FreeThreadedXMLDOM.1.0" }, + { "MSXML.FreeThreadedDOMDocument26", + "Free threaded XML DOM Document 2.6", + &CLSID_FreeThreadedDOMDocument26, + NULL + }, + { "MSXML.FreeThreadedDOMDocument30", + "Free threaded XML DOM Document 3.0", + &CLSID_FreeThreadedDOMDocument30, + NULL + }, { "Microsoft.XMLHTTP", "XML HTTP Request", &CLSID_XMLHTTPRequest, @@ -672,6 +721,11 @@ static struct progid const progid_list[] = { &CLSID_XMLSchemaCache, "Msxml2.XMLSchemaCache.3.0" }, + { "Msxml2.XMLSchemaCache.2.6", + "XML Schema Cache 2.6", + &CLSID_XMLSchemaCache26, + "Msxml2.XMLSchemaCache.2.6" + }, { "Msxml2.XMLSchemaCache.3.0", "XML Schema Cache 3.0", &CLSID_XMLSchemaCache30, @@ -697,7 +751,16 @@ static struct progid const progid_list[] = { &CLSID_MXXMLWriter30, NULL }, - + { "Msxml2.SAXAttributes", + "SAX Attribute", + &CLSID_SAXAttributes, + NULL + }, + { "Msxml2.SAXAttributes.3.0", + "SAX Attribute 3.0", + &CLSID_SAXAttributes30, + NULL + }, { NULL } /* list terminator */ }; diff --git a/dll/win32/netshell/res/neterror.ico b/dll/win32/netshell/res/neterror.ico index c80f6b7c97d..f20a0a4995b 100644 Binary files a/dll/win32/netshell/res/neterror.ico and b/dll/win32/netshell/res/neterror.ico differ diff --git a/dll/win32/netshell/res/netidle.ico b/dll/win32/netshell/res/netidle.ico index fbbdd17da96..6c175cc3d3c 100644 Binary files a/dll/win32/netshell/res/netidle.ico and b/dll/win32/netshell/res/netidle.ico differ diff --git a/dll/win32/netshell/res/netoff.ico b/dll/win32/netshell/res/netoff.ico index 0d3bb295e2a..9cb3f62e895 100644 Binary files a/dll/win32/netshell/res/netoff.ico and b/dll/win32/netshell/res/netoff.ico differ diff --git a/dll/win32/netshell/res/netrec.ico b/dll/win32/netshell/res/netrec.ico index 5aaffe27e6e..3ada0c28d99 100644 Binary files a/dll/win32/netshell/res/netrec.ico and b/dll/win32/netshell/res/netrec.ico differ diff --git a/dll/win32/netshell/res/nettrans.ico b/dll/win32/netshell/res/nettrans.ico index b3f647f20e9..cfad0528c99 100644 Binary files a/dll/win32/netshell/res/nettrans.ico and b/dll/win32/netshell/res/nettrans.ico differ diff --git a/dll/win32/netshell/res/nettrrec.ico b/dll/win32/netshell/res/nettrrec.ico index 8c7420827c1..27a2c1aaf4d 100644 Binary files a/dll/win32/netshell/res/nettrrec.ico and b/dll/win32/netshell/res/nettrrec.ico differ diff --git a/dll/win32/odbccp32/odbccp32.rbuild b/dll/win32/odbccp32/odbccp32.rbuild index 253485a359e..15bb8d84bb4 100644 --- a/dll/win32/odbccp32/odbccp32.rbuild +++ b/dll/win32/odbccp32/odbccp32.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/dll/win32/ole32/clipboard.c b/dll/win32/ole32/clipboard.c index 2afc77e35f0..3064bb04156 100644 --- a/dll/win32/ole32/clipboard.c +++ b/dll/win32/ole32/clipboard.c @@ -1266,10 +1266,10 @@ static HRESULT WINAPI snapshot_GetDataHere(IDataObject *iface, FORMATETC *fmt, ole_priv_data_entry *entry; TYMED supported; - TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed); - if ( !fmt || !med ) return E_INVALIDARG; + TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed); + if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN; if(!This->data) diff --git a/dll/win32/ole32/comcat.c b/dll/win32/ole32/comcat.c index b8060bdefca..fe0f7e5962e 100644 --- a/dll/win32/ole32/comcat.c +++ b/dll/win32/ole32/comcat.c @@ -232,18 +232,20 @@ static HRESULT COMCAT_IsClassOfCategories( LPCWSTR string; /* Check that every given category is implemented by class. */ - res = RegOpenKeyExW(key, impl_keyname, 0, KEY_READ, &subkey); - if (res != ERROR_SUCCESS) return S_FALSE; - for (string = categories->impl_strings; *string; string += 39) { - HKEY catkey; - res = RegOpenKeyExW(subkey, string, 0, 0, &catkey); - if (res != ERROR_SUCCESS) { - RegCloseKey(subkey); - return S_FALSE; + if (*categories->impl_strings) { + res = RegOpenKeyExW(key, impl_keyname, 0, KEY_READ, &subkey); + if (res != ERROR_SUCCESS) return S_FALSE; + for (string = categories->impl_strings; *string; string += 39) { + HKEY catkey; + res = RegOpenKeyExW(subkey, string, 0, 0, &catkey); + if (res != ERROR_SUCCESS) { + RegCloseKey(subkey); + return S_FALSE; + } + RegCloseKey(catkey); } - RegCloseKey(catkey); + RegCloseKey(subkey); } - RegCloseKey(subkey); /* Check that all categories required by class are given. */ res = RegOpenKeyExW(key, req_keyname, 0, KEY_READ, &subkey); diff --git a/dll/win32/ole32/compobj.c b/dll/win32/ole32/compobj.c index 0fb074dc50c..937f3d8a06c 100644 --- a/dll/win32/ole32/compobj.c +++ b/dll/win32/ole32/compobj.c @@ -4156,7 +4156,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) break; case DLL_PROCESS_DETACH: - OLEDD_UnInitialize(); COMPOBJ_UninitProcess(); RPC_UnregisterAllChannelHooks(); COMPOBJ_DllList_Free(); diff --git a/dll/win32/ole32/compositemoniker.c b/dll/win32/ole32/compositemoniker.c index 7402b8edbbf..275d875362b 100644 --- a/dll/win32/ole32/compositemoniker.c +++ b/dll/win32/ole32/compositemoniker.c @@ -445,7 +445,6 @@ static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar, IMoniker** ppmkToLeft, IMoniker** ppmkReduced) { - HRESULT res; IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk; IEnumMoniker *enumMoniker; @@ -462,8 +461,8 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); IEnumMoniker_Release(enumMoniker); - res=CreateAntiMoniker(&antiMk); - res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + CreateAntiMoniker(&antiMk); + IMoniker_ComposeWith(iface,antiMk,0,&tempMk); IMoniker_Release(antiMk); return IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced); @@ -479,8 +478,8 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); IEnumMoniker_Release(enumMoniker); - res=CreateAntiMoniker(&antiMk); - res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + CreateAntiMoniker(&antiMk); + IMoniker_ComposeWith(iface,antiMk,0,&tempMk); IMoniker_Release(antiMk); /* If any of the components reduces itself, the method returns S_OK and passes back a composite */ diff --git a/dll/win32/ole32/defaulthandler.c b/dll/win32/ole32/defaulthandler.c index 5130513d57f..d0a871f17c0 100644 --- a/dll/win32/ole32/defaulthandler.c +++ b/dll/win32/ole32/defaulthandler.c @@ -365,7 +365,7 @@ static HRESULT WINAPI DefaultHandler_SetClientSite( if (This->clientSite) IOleClientSite_AddRef(This->clientSite); - return S_OK; + return hr; } /************************************************************************ diff --git a/dll/win32/ole32/hglobalstream.c b/dll/win32/ole32/hglobalstream.c index 5742f99619a..ef616defec5 100644 --- a/dll/win32/ole32/hglobalstream.c +++ b/dll/win32/ole32/hglobalstream.c @@ -371,12 +371,6 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart, dlibMove.u.LowPart, dwOrigin, plibNewPosition); - if (dlibMove.u.LowPart >= 0x80000000) - { - hr = STG_E_SEEKERROR; - goto end; - } - /* * The file pointer is moved depending on the given "function" * parameter. @@ -405,10 +399,19 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( newPosition.u.HighPart = 0; newPosition.u.LowPart += dlibMove.QuadPart; -end: - if (plibNewPosition) *plibNewPosition = newPosition; + if (dlibMove.u.LowPart >= 0x80000000 && + newPosition.u.LowPart >= dlibMove.u.LowPart) + { + /* We tried to seek backwards and went past the start. */ + hr = STG_E_SEEKERROR; + goto end; + } + This->currentPosition = newPosition; +end: + if (plibNewPosition) *plibNewPosition = This->currentPosition; + return hr; } diff --git a/dll/win32/ole32/ifs.c b/dll/win32/ole32/ifs.c index c6a6962cd72..1a10c3e1f53 100644 --- a/dll/win32/ole32/ifs.c +++ b/dll/win32/ole32/ifs.c @@ -501,7 +501,7 @@ HRESULT WINAPI CoRevokeMallocSpy(void) } LeaveCriticalSection(&IMalloc32_SpyCS); - return S_OK; + return hres; } /****************************************************************************** diff --git a/dll/win32/ole32/marshal.c b/dll/win32/ole32/marshal.c index 54a3a87b2b6..d14516f6dec 100644 --- a/dll/win32/ole32/marshal.c +++ b/dll/win32/ole32/marshal.c @@ -1214,16 +1214,13 @@ StdMarshalImpl_MarshalInterface( RPC_StartRemoting(apt); hres = marshal_object(apt, &stdobjref, riid, pv, mshlflags); - if (hres) + if (hres != S_OK) { ERR("Failed to create ifstub, hres=0x%x\n", hres); return hres; } - hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres) return hres; - - return S_OK; + return IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res); } /* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with @@ -1321,10 +1318,10 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v /* read STDOBJREF from wire */ hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres) return STG_E_READFAULT; + if (hres != S_OK) return STG_E_READFAULT; hres = apartment_getoxid(apt, &oxid); - if (hres) return hres; + if (hres != S_OK) return hres; /* check if we're marshalling back to ourselves */ if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid))) @@ -1374,7 +1371,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v if (stubmgr) stub_manager_int_release(stubmgr); if (stub_apt) apartment_release(stub_apt); - if (hres) WARN("Failed with error 0x%08x\n", hres); + if (hres != S_OK) WARN("Failed with error 0x%08x\n", hres); else TRACE("Successfully created proxy %p\n", *ppv); return hres; @@ -1392,7 +1389,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) TRACE("iface=%p, pStm=%p\n", iface, pStm); hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres) return STG_E_READFAULT; + if (hres != S_OK) return STG_E_READFAULT; TRACE("oxid = %s, oid = %s, ipid = %s\n", wine_dbgstr_longlong(stdobjref.oxid), @@ -1516,7 +1513,7 @@ static HRESULT get_marshaler(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, if (!pUnk) return E_POINTER; hr = IUnknown_QueryInterface(pUnk, &IID_IMarshal, (LPVOID*)pMarshal); - if (hr) + if (hr != S_OK) hr = CoGetStandardMarshal(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, pMarshal); return hr; @@ -1537,7 +1534,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, /* read common OBJREF header */ hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res); - if (hr || (res != FIELD_OFFSET(OBJREF, u_objref))) + if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref))) { ERR("Failed to read common OBJREF header, 0x%08x\n", hr); return STG_E_READFAULT; @@ -1566,7 +1563,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, /* read constant sized OR_CUSTOM data from stream */ hr = IStream_Read(stream, &objref.u_objref.u_custom, custom_header_size, &res); - if (hr || (res != custom_header_size)) + if (hr != S_OK || (res != custom_header_size)) { ERR("Failed to read OR_CUSTOM header, 0x%08x\n", hr); return STG_E_READFAULT; @@ -1583,7 +1580,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, return RPC_E_INVALID_OBJREF; } - if (hr) + if (hr != S_OK) ERR("Failed to create marshal, 0x%08x\n", hr); return hr; @@ -1618,12 +1615,12 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk, CLSID marshaler_clsid; hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); - if (hr) + if (hr != S_OK) return hr; hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &marshaler_clsid); - if (hr) + if (hr != S_OK) { ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr); IMarshal_Release(pMarshal); @@ -1711,7 +1708,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, /* get the marshaler for the specified interface */ hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); - if (hr) + if (hr != S_OK) { ERR("Failed to get marshaller, 0x%08x\n", hr); return hr; @@ -1719,7 +1716,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &marshaler_clsid); - if (hr) + if (hr != S_OK) { ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr); goto cleanup; @@ -1733,7 +1730,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, /* write the common OBJREF header to the stream */ hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL); - if (hr) + if (hr != S_OK) { ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr); goto cleanup; @@ -1749,7 +1746,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &objref.u_objref.u_custom.size); - if (hr) + if (hr != S_OK) { ERR("Failed to get max size of marshal data, error 0x%08x\n", hr); goto cleanup; @@ -1757,7 +1754,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, /* write constant sized common header and OR_CUSTOM data into stream */ hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL); - if (hr) + if (hr != S_OK) { ERR("Failed to write OR_CUSTOM header to stream with 0x%08x\n", hr); goto cleanup; @@ -1769,7 +1766,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, hr = IMarshal_MarshalInterface(pMarshal, pStream, riid, pUnk, dwDestContext, pvDestContext, mshlFlags); - if (hr) + if (hr != S_OK) { ERR("Failed to marshal the interface %s, %x\n", debugstr_guid(riid), hr); goto cleanup; @@ -1821,7 +1818,7 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) /* call the helper object to do the actual unmarshaling */ hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object); - if (hr) + if (hr != S_OK) ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr); if (hr == S_OK) @@ -1831,7 +1828,7 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) { TRACE("requested interface != marshalled interface, additional QI needed\n"); hr = IUnknown_QueryInterface(object, riid, ppv); - if (hr) + if (hr != S_OK) ERR("Couldn't query for interface %s, hr = 0x%08x\n", debugstr_guid(riid), hr); IUnknown_Release(object); @@ -1885,7 +1882,7 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream) /* call the helper object to do the releasing of marshal data */ hr = IMarshal_ReleaseMarshalData(pMarshal, pStream); - if (hr) + if (hr != S_OK) ERR("IMarshal::ReleaseMarshalData failed with error 0x%08x\n", hr); IMarshal_Release(pMarshal); diff --git a/dll/win32/ole32/moniker.c b/dll/win32/ole32/moniker.c index 2fb03ae6650..b0030dee59b 100644 --- a/dll/win32/ole32/moniker.c +++ b/dll/win32/ole32/moniker.c @@ -1109,7 +1109,13 @@ HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName, TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk); - if (!(IsValidInterface((LPUNKNOWN) pbc))) + if (!pbc || !IsValidInterface((LPUNKNOWN) pbc)) + return E_INVALIDARG; + + if (!szDisplayName || !*szDisplayName) + return E_INVALIDARG; + + if (!pchEaten || !ppmk) return E_INVALIDARG; *pchEaten = 0; diff --git a/dll/win32/ole32/ole2.c b/dll/win32/ole32/ole2.c index 6bf79fdb507..41989f3331b 100644 --- a/dll/win32/ole32/ole2.c +++ b/dll/win32/ole32/ole2.c @@ -57,13 +57,6 @@ WINE_DECLARE_DEBUG_CHANNEL(accel); * These are static/global variables and internal data structures that the * OLE module uses to maintain it's state. */ -typedef struct tagDropTargetNode -{ - HWND hwndTarget; - IDropTarget* dropTarget; - struct list entry; -} DropTargetNode; - typedef struct tagTrackerWindowInfo { IDataObject* dataObject; @@ -110,12 +103,25 @@ static LONG OLE_moduleLockCount = 0; /* * Name of our registered window class. */ -static const char OLEDD_DRAGTRACKERCLASS[] = "WineDragDropTracker32"; +static const WCHAR OLEDD_DRAGTRACKERCLASS[] = + {'W','i','n','e','D','r','a','g','D','r','o','p','T','r','a','c','k','e','r','3','2',0}; /* - * This is the head of the Drop target container. + * Name of menu descriptor property. */ -static struct list targetListHead = LIST_INIT(targetListHead); +static const WCHAR prop_olemenuW[] = + {'P','R','O','P','_','O','L','E','M','e','n','u','D','e','s','c','r','i','p','t','o','r',0}; + +/* property to store IDropTarget pointer */ +static const WCHAR prop_oledroptarget[] = + {'O','l','e','D','r','o','p','T','a','r','g','e','t','I','n','t','e','r','f','a','c','e',0}; + +static const WCHAR clsidfmtW[] = + {'C','L','S','I','D','\\','{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-', + '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x', + '%','0','2','x','%','0','2','x','}','\\',0}; + +static const WCHAR emptyW[] = { 0 }; /****************************************************************************** * These are the prototypes of miscellaneous utility methods @@ -144,22 +150,12 @@ extern void OLEClipbrd_Initialize(void); /****************************************************************************** * These are the prototypes of the utility methods used for OLE Drag n Drop */ -static void OLEDD_Initialize(void); -static DropTargetNode* OLEDD_FindDropTarget( - HWND hwndOfTarget); -static void OLEDD_FreeDropTarget(DropTargetNode*, BOOL); -static LRESULT WINAPI OLEDD_DragTrackerWindowProc( - HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam); -static void OLEDD_TrackMouseMove( - TrackerWindowInfo* trackerInfo); -static void OLEDD_TrackStateChange( - TrackerWindowInfo* trackerInfo); +static void OLEDD_Initialize(void); +static LRESULT WINAPI OLEDD_DragTrackerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo); +static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo); static DWORD OLEDD_GetButtonState(void); - /****************************************************************************** * OleBuildVersion [OLE32.@] */ @@ -270,14 +266,22 @@ HRESULT WINAPI OleInitializeWOW(DWORD x, DWORD y) { return 0; } +/*** + * OLEDD_FindDropTarget() + * + * Returns IDropTarget pointer registered for this window. + */ +static inline IDropTarget* OLEDD_FindDropTarget(HWND hwnd) +{ + return GetPropW(hwnd, prop_oledroptarget); +} + /*********************************************************************** * RegisterDragDrop (OLE32.@) */ -HRESULT WINAPI RegisterDragDrop( - HWND hwnd, - LPDROPTARGET pDropTarget) +HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget) { - DropTargetNode* dropTargetInfo; + DWORD pid = 0; TRACE("(%p,%p)\n", hwnd, pDropTarget); @@ -296,32 +300,20 @@ HRESULT WINAPI RegisterDragDrop( return DRAGDROP_E_INVALIDHWND; } - /* - * First, check if the window is already registered. - */ - dropTargetInfo = OLEDD_FindDropTarget(hwnd); + /* block register for other processes windows */ + GetWindowThreadProcessId(hwnd, &pid); + if (pid != GetCurrentProcessId()) + { + FIXME("register for another process windows is disabled\n"); + return DRAGDROP_E_INVALIDHWND; + } - if (dropTargetInfo!=NULL) + /* check if the window is already registered */ + if (OLEDD_FindDropTarget(hwnd)) return DRAGDROP_E_ALREADYREGISTERED; - /* - * If it's not there, we can add it. We first create a node for it. - */ - dropTargetInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode)); - - if (dropTargetInfo==NULL) - return E_OUTOFMEMORY; - - dropTargetInfo->hwndTarget = hwnd; - - /* - * Don't forget that this is an interface pointer, need to nail it down since - * we keep a copy of it. - */ IDropTarget_AddRef(pDropTarget); - dropTargetInfo->dropTarget = pDropTarget; - - list_add_tail(&targetListHead, &dropTargetInfo->entry); + SetPropW(hwnd, prop_oledroptarget, pDropTarget); return S_OK; } @@ -329,10 +321,9 @@ HRESULT WINAPI RegisterDragDrop( /*********************************************************************** * RevokeDragDrop (OLE32.@) */ -HRESULT WINAPI RevokeDragDrop( - HWND hwnd) +HRESULT WINAPI RevokeDragDrop(HWND hwnd) { - DropTargetNode* dropTargetInfo; + IDropTarget* droptarget; TRACE("(%p)\n", hwnd); @@ -342,18 +333,12 @@ HRESULT WINAPI RevokeDragDrop( return DRAGDROP_E_INVALIDHWND; } - /* - * First, check if the window is already registered. - */ - dropTargetInfo = OLEDD_FindDropTarget(hwnd); - - /* - * If it ain't in there, it's an error. - */ - if (dropTargetInfo==NULL) + /* no registration data */ + if (!(droptarget = OLEDD_FindDropTarget(hwnd))) return DRAGDROP_E_NOTREGISTERED; - OLEDD_FreeDropTarget(dropTargetInfo, TRUE); + IDropTarget_Release(droptarget); + RemovePropW(hwnd, prop_oledroptarget); return S_OK; } @@ -371,13 +356,12 @@ HRESULT WINAPI OleRegGetUserType( DWORD dwFormOfType, LPOLESTR* pszUserType) { - char keyName[60]; + WCHAR keyName[60]; DWORD dwKeyType; DWORD cbData; HKEY clsidKey; LONG hres; - LPSTR buffer; - HRESULT retVal; + /* * Initialize the out parameter. */ @@ -386,17 +370,17 @@ HRESULT WINAPI OleRegGetUserType( /* * Build the key name we're looking for */ - sprintf( keyName, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\", - clsid->Data1, clsid->Data2, clsid->Data3, - clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], - clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); + sprintfW( keyName, clsidfmtW, + clsid->Data1, clsid->Data2, clsid->Data3, + clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], + clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); - TRACE("(%s, %d, %p)\n", keyName, dwFormOfType, pszUserType); + TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwFormOfType, pszUserType); /* * Open the class id Key */ - hres = RegOpenKeyA(HKEY_CLASSES_ROOT, + hres = RegOpenKeyW(HKEY_CLASSES_ROOT, keyName, &clsidKey); @@ -408,8 +392,8 @@ HRESULT WINAPI OleRegGetUserType( */ cbData = 0; - hres = RegQueryValueExA(clsidKey, - "", + hres = RegQueryValueExW(clsidKey, + emptyW, NULL, &dwKeyType, NULL, @@ -424,7 +408,7 @@ HRESULT WINAPI OleRegGetUserType( /* * Allocate a buffer for the registry value. */ - *pszUserType = CoTaskMemAlloc(cbData*2); + *pszUserType = CoTaskMemAlloc(cbData); if (*pszUserType==NULL) { @@ -432,41 +416,24 @@ HRESULT WINAPI OleRegGetUserType( return E_OUTOFMEMORY; } - buffer = HeapAlloc(GetProcessHeap(), 0, cbData); - - if (buffer == NULL) - { - RegCloseKey(clsidKey); - CoTaskMemFree(*pszUserType); - *pszUserType=NULL; - return E_OUTOFMEMORY; - } - - hres = RegQueryValueExA(clsidKey, - "", + hres = RegQueryValueExW(clsidKey, + emptyW, NULL, &dwKeyType, - (LPBYTE) buffer, + (LPBYTE) *pszUserType, &cbData); RegCloseKey(clsidKey); - - if (hres!=ERROR_SUCCESS) + if (hres != ERROR_SUCCESS) { CoTaskMemFree(*pszUserType); - *pszUserType=NULL; + *pszUserType = NULL; - retVal = REGDB_E_READREGDB; + return REGDB_E_READREGDB; } - else - { - MultiByteToWideChar( CP_ACP, 0, buffer, -1, *pszUserType, cbData /*FIXME*/ ); - retVal = S_OK; - } - HeapFree(GetProcessHeap(), 0, buffer); - return retVal; + return S_OK; } /*********************************************************************** @@ -478,17 +445,19 @@ HRESULT WINAPI DoDragDrop ( DWORD dwOKEffect, /* [in] effects allowed by the source */ DWORD *pdwEffect) /* [out] ptr to effects of the source */ { + static const WCHAR trackerW[] = {'T','r','a','c','k','e','r','W','i','n','d','o','w',0}; TrackerWindowInfo trackerInfo; HWND hwndTrackWindow; MSG msg; - TRACE("(DataObject %p, DropSource %p)\n", pDataObject, pDropSource); + TRACE("(%p, %p, %d, %p)\n", pDataObject, pDropSource, dwOKEffect, pdwEffect); + + if (!pDataObject || !pDropSource || !pdwEffect) + return E_INVALIDARG; /* * Setup the drag n drop tracking window. */ - if (!IsValidInterface((LPUNKNOWN)pDropSource)) - return E_INVALIDARG; trackerInfo.dataObject = pDataObject; trackerInfo.dropSource = pDropSource; @@ -500,12 +469,12 @@ HRESULT WINAPI DoDragDrop ( trackerInfo.curTargetHWND = 0; trackerInfo.curDragTarget = 0; - hwndTrackWindow = CreateWindowA(OLEDD_DRAGTRACKERCLASS, "TrackerWindow", + hwndTrackWindow = CreateWindowW(OLEDD_DRAGTRACKERCLASS, trackerW, WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, 0, &trackerInfo); - if (hwndTrackWindow!=0) + if (hwndTrackWindow) { /* * Capture the mouse input @@ -517,7 +486,7 @@ HRESULT WINAPI DoDragDrop ( /* * Pump messages. All mouse input should go to the capture window. */ - while (!trackerInfo.trackingDone && GetMessageA(&msg, 0, 0, 0) ) + while (!trackerInfo.trackingDone && GetMessageW(&msg, 0, 0, 0) ) { trackerInfo.curMousePos.x = msg.pt.x; trackerInfo.curMousePos.y = msg.pt.y; @@ -548,7 +517,7 @@ HRESULT WINAPI DoDragDrop ( /* * Dispatch the messages only when it's not a keyboard message. */ - DispatchMessageA(&msg); + DispatchMessageW(&msg); } } @@ -584,7 +553,9 @@ HRESULT WINAPI OleRegGetMiscStatus( DWORD dwAspect, DWORD* pdwStatus) { - char keyName[60]; + static const WCHAR miscstatusW[] = {'M','i','s','c','S','t','a','t','u','s',0}; + static const WCHAR dfmtW[] = {'%','d',0}; + WCHAR keyName[60]; HKEY clsidKey; HKEY miscStatusKey; HKEY aspectKey; @@ -598,17 +569,17 @@ HRESULT WINAPI OleRegGetMiscStatus( /* * Build the key name we're looking for */ - sprintf( keyName, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\", - clsid->Data1, clsid->Data2, clsid->Data3, - clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], - clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); + sprintfW( keyName, clsidfmtW, + clsid->Data1, clsid->Data2, clsid->Data3, + clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], + clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); - TRACE("(%s, %d, %p)\n", keyName, dwAspect, pdwStatus); + TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwAspect, pdwStatus); /* * Open the class id Key */ - result = RegOpenKeyA(HKEY_CLASSES_ROOT, + result = RegOpenKeyW(HKEY_CLASSES_ROOT, keyName, &clsidKey); @@ -618,8 +589,8 @@ HRESULT WINAPI OleRegGetMiscStatus( /* * Get the MiscStatus */ - result = RegOpenKeyA(clsidKey, - "MiscStatus", + result = RegOpenKeyW(clsidKey, + miscstatusW, &miscStatusKey); @@ -637,9 +608,9 @@ HRESULT WINAPI OleRegGetMiscStatus( /* * Open the key specific to the requested aspect. */ - sprintf(keyName, "%d", dwAspect); + sprintfW(keyName, dfmtW, dwAspect); - result = RegOpenKeyA(miscStatusKey, + result = RegOpenKeyW(miscStatusKey, keyName, &aspectKey); @@ -1180,7 +1151,7 @@ static void OLEMenu_UnInitialize(void) */ static BOOL OLEMenu_InstallHooks( DWORD tid ) { - OleMenuHookItem *pHookItem = NULL; + OleMenuHookItem *pHookItem; /* Create an entry for the hook table */ if ( !(pHookItem = HeapAlloc(GetProcessHeap(), 0, @@ -1189,15 +1160,16 @@ static BOOL OLEMenu_InstallHooks( DWORD tid ) pHookItem->tid = tid; pHookItem->hHeap = GetProcessHeap(); + pHookItem->CallWndProc_hHook = NULL; /* Install a thread scope message hook for WH_GETMESSAGE */ - pHookItem->GetMsg_hHook = SetWindowsHookExA( WH_GETMESSAGE, OLEMenu_GetMsgProc, + pHookItem->GetMsg_hHook = SetWindowsHookExW( WH_GETMESSAGE, OLEMenu_GetMsgProc, 0, GetCurrentThreadId() ); if ( !pHookItem->GetMsg_hHook ) goto CLEANUP; /* Install a thread scope message hook for WH_CALLWNDPROC */ - pHookItem->CallWndProc_hHook = SetWindowsHookExA( WH_CALLWNDPROC, OLEMenu_CallWndProc, + pHookItem->CallWndProc_hHook = SetWindowsHookExW( WH_CALLWNDPROC, OLEMenu_CallWndProc, 0, GetCurrentThreadId() ); if ( !pHookItem->CallWndProc_hHook ) goto CLEANUP; @@ -1271,7 +1243,7 @@ CLEANUP: */ static OleMenuHookItem * OLEMenu_IsHookInstalled( DWORD tid ) { - OleMenuHookItem *pHookItem = NULL; + OleMenuHookItem *pHookItem; /* Do a simple linear search for an entry whose tid matches ours. * We really need a map but efficiency is not a concern here. */ @@ -1376,7 +1348,7 @@ static BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDes */ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lParam) { - LPCWPSTRUCT pMsg = NULL; + LPCWPSTRUCT pMsg; HOLEMENU hOleMenu = 0; OleMenuDescriptor *pOleMenuDescriptor = NULL; OleMenuHookItem *pHookItem = NULL; @@ -1395,7 +1367,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar * If the window has an OLEMenu property we may need to dispatch * the menu message to its active objects window instead. */ - hOleMenu = GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" ); + hOleMenu = GetPropW( pMsg->hwnd, prop_olemenuW ); if ( !hOleMenu ) goto NEXTHOOK; @@ -1413,7 +1385,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar pOleMenuDescriptor->bIsServerItem = FALSE; /* Send this message to the server as well */ - SendMessageA( pOleMenuDescriptor->hwndActiveObject, + SendMessageW( pOleMenuDescriptor->hwndActiveObject, pMsg->message, pMsg->wParam, pMsg->lParam ); goto NEXTHOOK; } @@ -1454,7 +1426,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar /* If the message was for the server dispatch it accordingly */ if ( pOleMenuDescriptor->bIsServerItem ) { - SendMessageA( pOleMenuDescriptor->hwndActiveObject, + SendMessageW( pOleMenuDescriptor->hwndActiveObject, pMsg->message, pMsg->wParam, pMsg->lParam ); } @@ -1481,7 +1453,7 @@ NEXTHOOK: */ static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lParam) { - LPMSG pMsg = NULL; + LPMSG pMsg; HOLEMENU hOleMenu = 0; OleMenuDescriptor *pOleMenuDescriptor = NULL; OleMenuHookItem *pHookItem = NULL; @@ -1500,7 +1472,7 @@ static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lPara * If the window has an OLEMenu property we may need to dispatch * the menu message to its active objects window instead. */ - hOleMenu = GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" ); + hOleMenu = GetPropW( pMsg->hwnd, prop_olemenuW ); if ( !hOleMenu ) goto NEXTHOOK; @@ -1671,7 +1643,7 @@ HRESULT WINAPI OleSetMenuDescriptor( pOleMenuDescriptor = NULL; /* Add a menu descriptor windows property to the frame window */ - SetPropA( hwndFrame, "PROP_OLEMenuDescriptor", hOleMenu ); + SetPropW( hwndFrame, prop_olemenuW, hOleMenu ); /* Install thread scope message hooks for WH_GETMESSAGE and WH_CALLWNDPROC */ if ( !OLEMenu_InstallHooks( GetCurrentThreadId() ) ) @@ -1684,7 +1656,7 @@ HRESULT WINAPI OleSetMenuDescriptor( return E_FAIL; /* Remove the menu descriptor property from the frame window */ - RemovePropA( hwndFrame, "PROP_OLEMenuDescriptor" ); + RemovePropW( hwndFrame, prop_olemenuW ); } return S_OK; @@ -1870,9 +1842,9 @@ void WINAPI ReleaseStgMedium( */ static void OLEDD_Initialize(void) { - WNDCLASSA wndClass; + WNDCLASSW wndClass; - ZeroMemory (&wndClass, sizeof(WNDCLASSA)); + ZeroMemory (&wndClass, sizeof(WNDCLASSW)); wndClass.style = CS_GLOBALCLASS; wndClass.lpfnWndProc = OLEDD_DragTrackerWindowProc; wndClass.cbClsExtra = 0; @@ -1881,58 +1853,7 @@ static void OLEDD_Initialize(void) wndClass.hbrBackground = 0; wndClass.lpszClassName = OLEDD_DRAGTRACKERCLASS; - RegisterClassA (&wndClass); -} - -/*** - * OLEDD_FreeDropTarget() - * - * Frees the drag and drop data structure - */ -static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo, BOOL release_drop_target) -{ - list_remove(&dropTargetInfo->entry); - if (release_drop_target) IDropTarget_Release(dropTargetInfo->dropTarget); - HeapFree(GetProcessHeap(), 0, dropTargetInfo); -} - -/*** - * OLEDD_UnInitialize() - * - * Releases the OLE drag and drop data structures. - */ -void OLEDD_UnInitialize(void) -{ - /* - * Simply empty the list. - */ - while (!list_empty(&targetListHead)) - { - DropTargetNode* curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry); - OLEDD_FreeDropTarget(curNode, FALSE); - } -} - -/*** - * OLEDD_FindDropTarget() - * - * Finds information about the drop target. - */ -static DropTargetNode* OLEDD_FindDropTarget(HWND hwndOfTarget) -{ - DropTargetNode* curNode; - - /* - * Iterate the list to find the HWND value. - */ - LIST_FOR_EACH_ENTRY(curNode, &targetListHead, DropTargetNode, entry) - if (hwndOfTarget==curNode->hwndTarget) - return curNode; - - /* - * If we get here, the item is not in the list - */ - return NULL; + RegisterClassW (&wndClass); } /*** @@ -1958,7 +1879,7 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc( { LPCREATESTRUCTA createStruct = (LPCREATESTRUCTA)lParam; - SetWindowLongPtrA(hwnd, 0, (LONG_PTR)createStruct->lpCreateParams); + SetWindowLongPtrW(hwnd, 0, (LONG_PTR)createStruct->lpCreateParams); SetTimer(hwnd, DRAG_TIMER_ID, 50, NULL); break; @@ -1989,7 +1910,7 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc( /* * This is a window proc after all. Let's call the default. */ - return DefWindowProcA (hwnd, uMsg, wParam, lParam); + return DefWindowProcW (hwnd, uMsg, wParam, lParam); } /*** @@ -2038,46 +1959,65 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) } else { - DropTargetNode* newDropTargetNode = 0; - /* * If we changed window, we have to notify our old target and check for * the new one. */ - if (trackerInfo->curDragTarget!=0) - { + if (trackerInfo->curDragTarget) IDropTarget_DragLeave(trackerInfo->curDragTarget); - } /* * Make sure we're hovering over a window. */ - if (hwndNewTarget!=0) + if (hwndNewTarget) { /* * Find-out if there is a drag target under the mouse */ - HWND nexttar = hwndNewTarget; + HWND next_target_wnd = hwndNewTarget; + IDropTarget *new_target; + DWORD pid; + trackerInfo->curTargetHWND = hwndNewTarget; do { - newDropTargetNode = OLEDD_FindDropTarget(nexttar); - } while (!newDropTargetNode && (nexttar = GetParent(nexttar)) != 0); - if(nexttar) hwndNewTarget = nexttar; + new_target = OLEDD_FindDropTarget(next_target_wnd); + } while (!new_target && (next_target_wnd = GetParent(next_target_wnd))); - trackerInfo->curDragTargetHWND = hwndNewTarget; - trackerInfo->curDragTarget = newDropTargetNode ? newDropTargetNode->dropTarget : 0; + if (next_target_wnd) hwndNewTarget = next_target_wnd; + + GetWindowThreadProcessId(hwndNewTarget, &pid); + if (pid != GetCurrentProcessId()) + { + FIXME("drop to another process window is unsupported\n"); + trackerInfo->curDragTargetHWND = 0; + trackerInfo->curTargetHWND = 0; + trackerInfo->curDragTarget = 0; + } + else + { + trackerInfo->curDragTargetHWND = hwndNewTarget; + trackerInfo->curDragTarget = new_target; + } /* * If there is, notify it that we just dragged-in */ - if (trackerInfo->curDragTarget!=0) + if (trackerInfo->curDragTarget) { - IDropTarget_DragEnter(trackerInfo->curDragTarget, - trackerInfo->dataObject, - trackerInfo->dwKeyState, - trackerInfo->curMousePos, - trackerInfo->pdwEffect); + hr = IDropTarget_DragEnter(trackerInfo->curDragTarget, + trackerInfo->dataObject, + trackerInfo->dwKeyState, + trackerInfo->curMousePos, + trackerInfo->pdwEffect); + + /* failed DragEnter() means invalid target */ + if (hr != S_OK) + { + trackerInfo->curDragTargetHWND = 0; + trackerInfo->curTargetHWND = 0; + trackerInfo->curDragTarget = 0; + } } } else @@ -2110,24 +2050,28 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) * when that's the case, we must display the standard drag and drop * cursors. */ - if (hr==DRAGDROP_S_USEDEFAULTCURSORS) + if (hr == DRAGDROP_S_USEDEFAULTCURSORS) { + HCURSOR hCur; + if (*trackerInfo->pdwEffect & DROPEFFECT_MOVE) { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(1))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(1)); } else if (*trackerInfo->pdwEffect & DROPEFFECT_COPY) { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(2))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(2)); } else if (*trackerInfo->pdwEffect & DROPEFFECT_LINK) { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(3))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(3)); } else { - SetCursor(LoadCursorA(hProxyDll, MAKEINTRESOURCEA(0))); + hCur = LoadCursorW(hProxyDll, MAKEINTRESOURCEW(0)); } + + SetCursor(hCur); } } @@ -2174,7 +2118,7 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) * If we end-up over a target, drop the object in the target or * inform the target that the operation was cancelled. */ - if (trackerInfo->curDragTarget!=0) + if (trackerInfo->curDragTarget) { switch (trackerInfo->returnValue) { @@ -2183,14 +2127,16 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) * the drop target that we just dropped the object in it. */ case DRAGDROP_S_DROP: - { - IDropTarget_Drop(trackerInfo->curDragTarget, - trackerInfo->dataObject, - trackerInfo->dwKeyState, - trackerInfo->curMousePos, - trackerInfo->pdwEffect); - break; - } + if (*trackerInfo->pdwEffect != DROPEFFECT_NONE) + IDropTarget_Drop(trackerInfo->curDragTarget, + trackerInfo->dataObject, + trackerInfo->dwKeyState, + trackerInfo->curMousePos, + trackerInfo->pdwEffect); + else + IDropTarget_DragLeave(trackerInfo->curDragTarget); + break; + /* * If the source told us that we should cancel, fool the drop * target by telling it that the mouse left it's window. @@ -2256,13 +2202,13 @@ static void OLEUTL_ReadRegistryDWORDValue( HKEY regKey, DWORD* pdwValue) { - char buffer[20]; + WCHAR buffer[20]; + DWORD cbData = sizeof(buffer); DWORD dwKeyType; - DWORD cbData = 20; LONG lres; - lres = RegQueryValueExA(regKey, - "", + lres = RegQueryValueExW(regKey, + emptyW, NULL, &dwKeyType, (LPBYTE)buffer, @@ -2278,7 +2224,7 @@ static void OLEUTL_ReadRegistryDWORDValue( case REG_EXPAND_SZ: case REG_MULTI_SZ: case REG_SZ: - *pdwValue = (DWORD)strtoul(buffer, NULL, 10); + *pdwValue = (DWORD)strtoulW(buffer, NULL, 10); break; } } diff --git a/dll/win32/ole32/ole32.rbuild b/dll/win32/ole32/ole32.rbuild index 85710a6b20f..57c6b9f64a6 100644 --- a/dll/win32/ole32/ole32.rbuild +++ b/dll/win32/ole32/ole32.rbuild @@ -1,7 +1,7 @@ - + . diff --git a/dll/win32/ole32/stg_prop.c b/dll/win32/ole32/stg_prop.c index b3362bc21de..f887d10c0cf 100644 --- a/dll/win32/ole32/stg_prop.c +++ b/dll/win32/ole32/stg_prop.c @@ -1314,6 +1314,13 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This) hr = PropertyStorage_ReadFmtIdOffsetFromStream(This->stm, &fmtOffset); if (FAILED(hr)) goto end; + if (!IsEqualGUID(&fmtOffset.fmtid, &FMTID_DocSummaryInformation) && + !IsEqualGUID(&fmtOffset.fmtid, &FMTID_SummaryInformation)) + { + WARN("not reading unknown fmtid %s\n", debugstr_guid(&fmtOffset.fmtid)); + hr = S_FALSE; + goto end; + } if (fmtOffset.dwOffset > stat.cbSize.u.LowPart) { WARN("invalid offset %d (stream length is %d)\n", fmtOffset.dwOffset, diff --git a/dll/win32/ole32/storage32.c b/dll/win32/ole32/storage32.c index 434d8b24606..98df144976c 100644 --- a/dll/win32/ole32/storage32.c +++ b/dll/win32/ole32/storage32.c @@ -118,17 +118,61 @@ static BOOL StorageImpl_ReadDWordFromBigBlock( StorageImpl* This, static BOOL StorageBaseImpl_IsStreamOpen(StorageBaseImpl * stg, DirRef streamEntry); static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageEntry); +typedef struct TransactedDirEntry +{ + /* If applicable, a reference to the original DirEntry in the transacted + * parent. If this is a newly-created entry, DIRENTRY_NULL. */ + DirRef transactedParentEntry; + + /* True if this entry is being used. */ + int inuse; + + /* True if data is up to date. */ + int read; + + /* True if this entry has been modified. */ + int dirty; + + /* True if this entry's stream has been modified. */ + int stream_dirty; + + /* True if this entry has been deleted in the transacted storage, but the + * delete has not yet been committed. */ + int deleted; + + /* If this entry's stream has been modified, a reference to where the stream + * is stored in the snapshot file. */ + DirRef stream_entry; + + /* This directory entry's data, including any changes that have been made. */ + DirEntry data; + + /* A reference to the parent of this node. This is only valid while we are + * committing changes. */ + DirRef parent; + + /* A reference to a newly-created entry in the transacted parent. This is + * always equal to transactedParentEntry except when committing changes. */ + DirRef newTransactedParentEntry; +} TransactedDirEntry; + /**************************************************************************** - * Transacted storage object that reads/writes a snapshot file. + * Transacted storage object. */ typedef struct TransactedSnapshotImpl { struct StorageBaseImpl base; /* - * Changes are temporarily saved to the snapshot. + * Modified streams are temporarily saved to the scratch file. */ - StorageBaseImpl *snapshot; + StorageBaseImpl *scratch; + + /* The directory structure is kept here, so that we can track how these + * entries relate to those in the parent storage. */ + TransactedDirEntry *entries; + ULONG entries_size; + ULONG firstFreeEntry; /* * Changes are committed to the transacted parent. @@ -1296,46 +1340,6 @@ static HRESULT StorageImpl_DestroyDirEntry( } -/*************************************************************************** - * - * Internal Method - * - * Destroy an entry, its attached data, and all entries reachable from it. - */ -static HRESULT DestroyReachableEntries( - StorageBaseImpl *base, - DirRef index) -{ - HRESULT hr = S_OK; - DirEntry data; - ULARGE_INTEGER zero; - - zero.QuadPart = 0; - - if (index != DIRENTRY_NULL) - { - hr = StorageBaseImpl_ReadDirEntry(base, index, &data); - - if (SUCCEEDED(hr)) - hr = DestroyReachableEntries(base, data.dirRootEntry); - - if (SUCCEEDED(hr)) - hr = DestroyReachableEntries(base, data.leftChild); - - if (SUCCEEDED(hr)) - hr = DestroyReachableEntries(base, data.rightChild); - - if (SUCCEEDED(hr)) - hr = StorageBaseImpl_StreamSetSize(base, index, zero); - - if (SUCCEEDED(hr)) - hr = StorageBaseImpl_DestroyDirEntry(base, index); - } - - return hr; -} - - /**************************************************************************** * * Internal Method @@ -2347,6 +2351,21 @@ static BlockChainStream **StorageImpl_GetCachedBlockChainStream(StorageImpl *Thi return &This->blockChainCache[free_index]; } +static void StorageImpl_DeleteCachedBlockChainStream(StorageImpl *This, DirRef index) +{ + int i; + + for (i=0; iblockChainCache[i] && This->blockChainCache[i]->ownerDirEntry == index) + { + BlockChainStream_Destroy(This->blockChainCache[i]); + This->blockChainCache[i] = NULL; + return; + } + } +} + static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) { @@ -2538,6 +2557,30 @@ static HRESULT StorageImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, } } +static HRESULT StorageImpl_StreamLink(StorageBaseImpl *base, DirRef dst, + DirRef src) +{ + StorageImpl *This = (StorageImpl*)base; + DirEntry dst_data, src_data; + HRESULT hr; + + hr = StorageImpl_ReadDirEntry(This, dst, &dst_data); + + if (SUCCEEDED(hr)) + hr = StorageImpl_ReadDirEntry(This, src, &src_data); + + if (SUCCEEDED(hr)) + { + StorageImpl_DeleteCachedBlockChainStream(This, src); + dst_data.startingBlock = src_data.startingBlock; + dst_data.size = src_data.size; + + hr = StorageImpl_WriteDirEntry(This, dst, &dst_data); + } + + return hr; +} + /* * Virtual function table for the IStorage32Impl class. */ @@ -2573,7 +2616,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl = StorageImpl_DestroyDirEntry, StorageImpl_StreamReadAt, StorageImpl_StreamWriteAt, - StorageImpl_StreamSetSize + StorageImpl_StreamSetSize, + StorageImpl_StreamLink }; static HRESULT StorageImpl_Construct( @@ -3540,6 +3584,9 @@ HRESULT StorageImpl_ReadRawDirEntry(StorageImpl *This, ULONG index, BYTE *buffer buffer, &bytesRead); + if (bytesRead != RAW_DIRENTRY_SIZE) + return STG_E_READFAULT; + return hr; } @@ -3885,6 +3932,11 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( offset.u.LowPart += cbRead; } + else + { + resRead = STG_E_READFAULT; + break; + } } while (cbTotalRead.QuadPart < size.QuadPart); HeapFree(GetProcessHeap(),0,buffer); @@ -3983,6 +4035,11 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( offset.u.LowPart += cbRead; } + else + { + resRead = STG_E_READFAULT; + break; + } }while(cbTotalRead.QuadPart < size.QuadPart); HeapFree(GetProcessHeap(), 0, buffer); @@ -4011,40 +4068,384 @@ SmallBlockChainStream* Storage32Impl_BigBlocksToSmallBlocks( return SmallBlockChainStream_Construct(This, NULL, streamEntryRef); } -static HRESULT CreateSnapshotFile(StorageBaseImpl* original, StorageBaseImpl **snapshot) +static HRESULT StorageBaseImpl_CopyStream( + StorageBaseImpl *dst, DirRef dst_entry, + StorageBaseImpl *src, DirRef src_entry) { HRESULT hr; - DirEntry parentData, snapshotData; + BYTE data[4096]; + DirEntry srcdata; + ULARGE_INTEGER bytes_copied; + ULONG bytestocopy, bytesread, byteswritten; - hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DELETEONRELEASE, - 0, (IStorage**)snapshot); + hr = StorageBaseImpl_ReadDirEntry(src, src_entry, &srcdata); if (SUCCEEDED(hr)) { - hr = StorageBaseImpl_ReadDirEntry(original, - original->storageDirEntry, &parentData); + hr = StorageBaseImpl_StreamSetSize(dst, dst_entry, srcdata.size); - if (SUCCEEDED(hr)) - hr = StorageBaseImpl_ReadDirEntry((*snapshot), - (*snapshot)->storageDirEntry, &snapshotData); - - if (SUCCEEDED(hr)) + bytes_copied.QuadPart = 0; + while (bytes_copied.QuadPart < srcdata.size.QuadPart && SUCCEEDED(hr)) { - memcpy(snapshotData.name, parentData.name, sizeof(snapshotData.name)); - snapshotData.sizeOfNameString = parentData.sizeOfNameString; - snapshotData.stgType = parentData.stgType; - snapshotData.clsid = parentData.clsid; - snapshotData.ctime = parentData.ctime; - snapshotData.mtime = parentData.mtime; - hr = StorageBaseImpl_WriteDirEntry((*snapshot), - (*snapshot)->storageDirEntry, &snapshotData); + bytestocopy = min(4096, srcdata.size.QuadPart - bytes_copied.QuadPart); + + hr = StorageBaseImpl_StreamReadAt(src, src_entry, bytes_copied, bytestocopy, + data, &bytesread); + if (SUCCEEDED(hr) && bytesread != bytestocopy) hr = STG_E_READFAULT; + + if (SUCCEEDED(hr)) + hr = StorageBaseImpl_StreamWriteAt(dst, dst_entry, bytes_copied, bytestocopy, + data, &byteswritten); + if (SUCCEEDED(hr)) + { + if (byteswritten != bytestocopy) hr = STG_E_WRITEFAULT; + bytes_copied.QuadPart += byteswritten; + } + } + } + + return hr; +} + +static DirRef TransactedSnapshotImpl_FindFreeEntry(TransactedSnapshotImpl *This) +{ + DirRef result=This->firstFreeEntry; + + while (result < This->entries_size && This->entries[result].inuse) + result++; + + if (result == This->entries_size) + { + ULONG new_size = This->entries_size * 2; + TransactedDirEntry *new_entries; + + new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TransactedDirEntry) * new_size); + if (!new_entries) return DIRENTRY_NULL; + + memcpy(new_entries, This->entries, sizeof(TransactedDirEntry) * This->entries_size); + HeapFree(GetProcessHeap(), 0, This->entries); + + This->entries = new_entries; + This->entries_size = new_size; + } + + This->entries[result].inuse = 1; + + This->firstFreeEntry = result+1; + + return result; +} + +static DirRef TransactedSnapshotImpl_CreateStubEntry( + TransactedSnapshotImpl *This, DirRef parentEntryRef) +{ + DirRef stubEntryRef; + TransactedDirEntry *entry; + + stubEntryRef = TransactedSnapshotImpl_FindFreeEntry(This); + + if (stubEntryRef != DIRENTRY_NULL) + { + entry = &This->entries[stubEntryRef]; + + entry->newTransactedParentEntry = entry->transactedParentEntry = parentEntryRef; + + entry->read = 0; + } + + return stubEntryRef; +} + +static HRESULT TransactedSnapshotImpl_EnsureReadEntry( + TransactedSnapshotImpl *This, DirRef entry) +{ + HRESULT hr=S_OK; + DirEntry data; + + if (!This->entries[entry].read) + { + hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, + This->entries[entry].transactedParentEntry, + &data); + + if (SUCCEEDED(hr) && data.leftChild != DIRENTRY_NULL) + { + data.leftChild = TransactedSnapshotImpl_CreateStubEntry(This, data.leftChild); + + if (data.leftChild == DIRENTRY_NULL) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr) && data.rightChild != DIRENTRY_NULL) + { + data.rightChild = TransactedSnapshotImpl_CreateStubEntry(This, data.rightChild); + + if (data.rightChild == DIRENTRY_NULL) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr) && data.dirRootEntry != DIRENTRY_NULL) + { + data.dirRootEntry = TransactedSnapshotImpl_CreateStubEntry(This, data.dirRootEntry); + + if (data.dirRootEntry == DIRENTRY_NULL) + hr = E_OUTOFMEMORY; } if (SUCCEEDED(hr)) - hr = IStorage_CopyTo((IStorage*)original, 0, NULL, NULL, - (IStorage*)(*snapshot)); + { + memcpy(&This->entries[entry].data, &data, sizeof(DirEntry)); + This->entries[entry].read = 1; + } + } - if (FAILED(hr)) IStorage_Release((IStorage*)(*snapshot)); + return hr; +} + +static HRESULT TransactedSnapshotImpl_MakeStreamDirty( + TransactedSnapshotImpl *This, DirRef entry) +{ + HRESULT hr = S_OK; + + if (!This->entries[entry].stream_dirty) + { + DirEntry new_entrydata; + + memset(&new_entrydata, 0, sizeof(DirEntry)); + new_entrydata.name[0] = 'S'; + new_entrydata.sizeOfNameString = 1; + new_entrydata.stgType = STGTY_STREAM; + new_entrydata.startingBlock = BLOCK_END_OF_CHAIN; + new_entrydata.leftChild = DIRENTRY_NULL; + new_entrydata.rightChild = DIRENTRY_NULL; + new_entrydata.dirRootEntry = DIRENTRY_NULL; + + hr = StorageBaseImpl_CreateDirEntry(This->scratch, &new_entrydata, + &This->entries[entry].stream_entry); + + if (SUCCEEDED(hr) && This->entries[entry].transactedParentEntry != DIRENTRY_NULL) + { + hr = StorageBaseImpl_CopyStream( + This->scratch, This->entries[entry].stream_entry, + This->transactedParent, This->entries[entry].transactedParentEntry); + + if (FAILED(hr)) + StorageBaseImpl_DestroyDirEntry(This->scratch, This->entries[entry].stream_entry); + } + + if (SUCCEEDED(hr)) + This->entries[entry].stream_dirty = 1; + + if (This->entries[entry].transactedParentEntry != DIRENTRY_NULL) + { + /* Since this entry is modified, and we aren't using its stream data, we + * no longer care about the original entry. */ + DirRef delete_ref; + delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[entry].transactedParentEntry); + + if (delete_ref != DIRENTRY_NULL) + This->entries[delete_ref].deleted = 1; + + This->entries[entry].transactedParentEntry = This->entries[entry].newTransactedParentEntry = DIRENTRY_NULL; + } + } + + return hr; +} + +/* Find the first entry in a depth-first traversal. */ +static DirRef TransactedSnapshotImpl_FindFirstChild( + TransactedSnapshotImpl* This, DirRef parent) +{ + DirRef cursor, prev; + TransactedDirEntry *entry; + + cursor = parent; + entry = &This->entries[cursor]; + while (entry->read) + { + if (entry->data.leftChild != DIRENTRY_NULL) + { + prev = cursor; + cursor = entry->data.leftChild; + entry = &This->entries[cursor]; + entry->parent = prev; + } + else if (entry->data.rightChild != DIRENTRY_NULL) + { + prev = cursor; + cursor = entry->data.rightChild; + entry = &This->entries[cursor]; + entry->parent = prev; + } + else if (entry->data.dirRootEntry != DIRENTRY_NULL) + { + prev = cursor; + cursor = entry->data.dirRootEntry; + entry = &This->entries[cursor]; + entry->parent = prev; + } + else + break; + } + + return cursor; +} + +/* Find the next entry in a depth-first traversal. */ +static DirRef TransactedSnapshotImpl_FindNextChild( + TransactedSnapshotImpl* This, DirRef current) +{ + DirRef parent; + TransactedDirEntry *parent_entry; + + parent = This->entries[current].parent; + parent_entry = &This->entries[parent]; + + if (parent != DIRENTRY_NULL && parent_entry->data.dirRootEntry != current) + { + if (parent_entry->data.rightChild != current && parent_entry->data.rightChild != DIRENTRY_NULL) + { + This->entries[parent_entry->data.rightChild].parent = parent; + return TransactedSnapshotImpl_FindFirstChild(This, parent_entry->data.rightChild); + } + + if (parent_entry->data.dirRootEntry != DIRENTRY_NULL) + { + This->entries[parent_entry->data.dirRootEntry].parent = parent; + return TransactedSnapshotImpl_FindFirstChild(This, parent_entry->data.dirRootEntry); + } + } + + return parent; +} + +/* Return TRUE if we've made a copy of this entry for committing to the parent. */ +static inline BOOL TransactedSnapshotImpl_MadeCopy( + TransactedSnapshotImpl* This, DirRef entry) +{ + return entry != DIRENTRY_NULL && + This->entries[entry].newTransactedParentEntry != This->entries[entry].transactedParentEntry; +} + +/* Destroy the entries created by CopyTree. */ +static void TransactedSnapshotImpl_DestroyTemporaryCopy( + TransactedSnapshotImpl* This, DirRef stop) +{ + DirRef cursor; + TransactedDirEntry *entry; + ULARGE_INTEGER zero; + + zero.QuadPart = 0; + + if (!This->entries[This->base.storageDirEntry].read) + return; + + cursor = This->entries[This->base.storageDirEntry].data.dirRootEntry; + + if (cursor == DIRENTRY_NULL) + return; + + cursor = TransactedSnapshotImpl_FindFirstChild(This, cursor); + + while (cursor != DIRENTRY_NULL && cursor != stop) + { + if (TransactedSnapshotImpl_MadeCopy(This, cursor)) + { + entry = &This->entries[cursor]; + + if (entry->stream_dirty) + StorageBaseImpl_StreamSetSize(This->transactedParent, + entry->newTransactedParentEntry, zero); + + StorageBaseImpl_DestroyDirEntry(This->transactedParent, + entry->newTransactedParentEntry); + + entry->newTransactedParentEntry = entry->transactedParentEntry; + } + + cursor = TransactedSnapshotImpl_FindNextChild(This, cursor); + } +} + +/* Make a copy of our edited tree that we can use in the parent. */ +static HRESULT TransactedSnapshotImpl_CopyTree(TransactedSnapshotImpl* This) +{ + DirRef cursor; + TransactedDirEntry *entry; + HRESULT hr = S_OK; + + cursor = This->base.storageDirEntry; + entry = &This->entries[cursor]; + entry->parent = DIRENTRY_NULL; + entry->newTransactedParentEntry = entry->transactedParentEntry; + + if (entry->data.dirRootEntry == DIRENTRY_NULL) + return S_OK; + + This->entries[entry->data.dirRootEntry].parent = DIRENTRY_NULL; + + cursor = TransactedSnapshotImpl_FindFirstChild(This, entry->data.dirRootEntry); + entry = &This->entries[cursor]; + + while (cursor != DIRENTRY_NULL) + { + /* Make a copy of this entry in the transacted parent. */ + if (!entry->read || + (!entry->dirty && !entry->stream_dirty && + !TransactedSnapshotImpl_MadeCopy(This, entry->data.leftChild) && + !TransactedSnapshotImpl_MadeCopy(This, entry->data.rightChild) && + !TransactedSnapshotImpl_MadeCopy(This, entry->data.dirRootEntry))) + entry->newTransactedParentEntry = entry->transactedParentEntry; + else + { + DirEntry newData; + + memcpy(&newData, &entry->data, sizeof(DirEntry)); + + newData.size.QuadPart = 0; + newData.startingBlock = BLOCK_END_OF_CHAIN; + + if (newData.leftChild != DIRENTRY_NULL) + newData.leftChild = This->entries[newData.leftChild].newTransactedParentEntry; + + if (newData.rightChild != DIRENTRY_NULL) + newData.rightChild = This->entries[newData.rightChild].newTransactedParentEntry; + + if (newData.dirRootEntry != DIRENTRY_NULL) + newData.dirRootEntry = This->entries[newData.dirRootEntry].newTransactedParentEntry; + + hr = StorageBaseImpl_CreateDirEntry(This->transactedParent, &newData, + &entry->newTransactedParentEntry); + if (FAILED(hr)) + { + TransactedSnapshotImpl_DestroyTemporaryCopy(This, cursor); + return hr; + } + + if (entry->stream_dirty) + { + hr = StorageBaseImpl_CopyStream( + This->transactedParent, entry->newTransactedParentEntry, + This->scratch, entry->stream_entry); + } + else if (entry->data.size.QuadPart) + { + hr = StorageBaseImpl_StreamLink( + This->transactedParent, entry->newTransactedParentEntry, + entry->transactedParentEntry); + } + + if (FAILED(hr)) + { + cursor = TransactedSnapshotImpl_FindNextChild(This, cursor); + TransactedSnapshotImpl_DestroyTemporaryCopy(This, cursor); + return hr; + } + } + + cursor = TransactedSnapshotImpl_FindNextChild(This, cursor); + entry = &This->entries[cursor]; } return hr; @@ -4055,10 +4456,13 @@ static HRESULT WINAPI TransactedSnapshotImpl_Commit( DWORD grfCommitFlags) /* [in] */ { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; + TransactedDirEntry *root_entry; + DirRef i, dir_root_ref; + DirEntry data; + ULARGE_INTEGER zero; HRESULT hr; - DirEntry data, tempStorageData, snapshotRootData; - DirRef tempStorageEntry, oldDirRoot; - StorageInternalImpl *tempStorage; + + zero.QuadPart = 0; TRACE("(%p,%x)\n", iface, grfCommitFlags); @@ -4072,75 +4476,71 @@ static HRESULT WINAPI TransactedSnapshotImpl_Commit( * needed in the rare situation where we have just enough free disk space to * overwrite the existing data. */ - /* Create an orphaned storage in the parent for the new directory structure. */ - memset(&data, 0, sizeof(data)); - data.name[0] = 'D'; - data.sizeOfNameString = 1; - data.stgType = STGTY_STORAGE; - data.leftChild = DIRENTRY_NULL; - data.rightChild = DIRENTRY_NULL; - data.dirRootEntry = DIRENTRY_NULL; - hr = StorageBaseImpl_CreateDirEntry(This->transactedParent, &data, &tempStorageEntry); + root_entry = &This->entries[This->base.storageDirEntry]; + if (!root_entry->read) + return S_OK; + + hr = TransactedSnapshotImpl_CopyTree(This); if (FAILED(hr)) return hr; - tempStorage = StorageInternalImpl_Construct(This->transactedParent, - STGM_READWRITE|STGM_SHARE_EXCLUSIVE, tempStorageEntry); - if (tempStorage) - { - hr = IStorage_CopyTo((IStorage*)This->snapshot, 0, NULL, NULL, - (IStorage*)tempStorage); - - list_init(&tempStorage->ParentListEntry); - - IStorage_Release((IStorage*) tempStorage); - } + if (root_entry->data.dirRootEntry == DIRENTRY_NULL) + dir_root_ref = DIRENTRY_NULL; else - hr = E_OUTOFMEMORY; - - if (FAILED(hr)) - { - DestroyReachableEntries(This->transactedParent, tempStorageEntry); - return hr; - } + dir_root_ref = This->entries[root_entry->data.dirRootEntry].newTransactedParentEntry; /* Update the storage to use the new data in one step. */ hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, - This->transactedParent->storageDirEntry, &data); + root_entry->transactedParentEntry, &data); if (SUCCEEDED(hr)) { - hr = StorageBaseImpl_ReadDirEntry(This->transactedParent, - tempStorageEntry, &tempStorageData); - } - - if (SUCCEEDED(hr)) - { - hr = StorageBaseImpl_ReadDirEntry(This->snapshot, - This->snapshot->storageDirEntry, &snapshotRootData); - } - - if (SUCCEEDED(hr)) - { - oldDirRoot = data.dirRootEntry; - data.dirRootEntry = tempStorageData.dirRootEntry; - data.clsid = snapshotRootData.clsid; - data.ctime = snapshotRootData.ctime; - data.mtime = snapshotRootData.mtime; + data.dirRootEntry = dir_root_ref; + data.clsid = root_entry->data.clsid; + data.ctime = root_entry->data.ctime; + data.mtime = root_entry->data.mtime; hr = StorageBaseImpl_WriteDirEntry(This->transactedParent, - This->transactedParent->storageDirEntry, &data); + root_entry->transactedParentEntry, &data); } if (SUCCEEDED(hr)) { /* Destroy the old now-orphaned data. */ - DestroyReachableEntries(This->transactedParent, oldDirRoot); - StorageBaseImpl_DestroyDirEntry(This->transactedParent, tempStorageEntry); + for (i=0; ientries_size; i++) + { + TransactedDirEntry *entry = &This->entries[i]; + if (entry->inuse) + { + if (entry->deleted) + { + StorageBaseImpl_StreamSetSize(This->transactedParent, + entry->transactedParentEntry, zero); + StorageBaseImpl_DestroyDirEntry(This->transactedParent, + entry->transactedParentEntry); + memset(entry, 0, sizeof(TransactedDirEntry)); + This->firstFreeEntry = min(i, This->firstFreeEntry); + } + else if (entry->read && entry->transactedParentEntry != entry->newTransactedParentEntry) + { + if (entry->transactedParentEntry != DIRENTRY_NULL) + StorageBaseImpl_DestroyDirEntry(This->transactedParent, + entry->transactedParentEntry); + if (entry->stream_dirty) + { + StorageBaseImpl_StreamSetSize(This->scratch, entry->stream_entry, zero); + StorageBaseImpl_DestroyDirEntry(This->scratch, entry->stream_entry); + entry->stream_dirty = 0; + } + entry->dirty = 0; + entry->transactedParentEntry = entry->newTransactedParentEntry; + } + } + } } else { - DestroyReachableEntries(This->transactedParent, tempStorageEntry); + TransactedSnapshotImpl_DestroyTemporaryCopy(This, DIRENTRY_NULL); } return hr; @@ -4150,21 +4550,31 @@ static HRESULT WINAPI TransactedSnapshotImpl_Revert( IStorage* iface) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; - StorageBaseImpl *newSnapshot; - HRESULT hr; + ULARGE_INTEGER zero; + ULONG i; TRACE("(%p)\n", iface); - /* Create a new copy of the parent data. */ - hr = CreateSnapshotFile(This->transactedParent, &newSnapshot); - if (FAILED(hr)) return hr; - /* Destroy the open objects. */ StorageBaseImpl_DeleteAll(&This->base); - /* Replace our current snapshot. */ - IStorage_Release((IStorage*)This->snapshot); - This->snapshot = newSnapshot; + /* Clear out the scratch file. */ + zero.QuadPart = 0; + for (i=0; ientries_size; i++) + { + if (This->entries[i].stream_dirty) + { + StorageBaseImpl_StreamSetSize(This->scratch, This->entries[i].stream_entry, + zero); + + StorageBaseImpl_DestroyDirEntry(This->scratch, This->entries[i].stream_entry); + } + } + + memset(This->entries, 0, sizeof(TransactedDirEntry) * This->entries_size); + + This->firstFreeEntry = 0; + This->base.storageDirEntry = TransactedSnapshotImpl_CreateStubEntry(This, This->transactedParent->storageDirEntry); return S_OK; } @@ -4185,11 +4595,13 @@ static void TransactedSnapshotImpl_Destroy( StorageBaseImpl *iface) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface; - TransactedSnapshotImpl_Invalidate(iface); + TransactedSnapshotImpl_Revert((IStorage*)iface); IStorage_Release((IStorage*)This->transactedParent); - IStorage_Release((IStorage*)This->snapshot); + IStorage_Release((IStorage*)This->scratch); + + HeapFree(GetProcessHeap(), 0, This->entries); HeapFree(GetProcessHeap(), 0, This); } @@ -4198,27 +4610,76 @@ static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base, const DirEntry *newData, DirRef *index) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + DirRef new_ref; + TransactedDirEntry *new_entry; - return StorageBaseImpl_CreateDirEntry(This->snapshot, - newData, index); + new_ref = TransactedSnapshotImpl_FindFreeEntry(This); + if (new_ref == DIRENTRY_NULL) + return E_OUTOFMEMORY; + + new_entry = &This->entries[new_ref]; + + new_entry->newTransactedParentEntry = new_entry->transactedParentEntry = DIRENTRY_NULL; + new_entry->read = 1; + new_entry->dirty = 1; + memcpy(&new_entry->data, newData, sizeof(DirEntry)); + + *index = new_ref; + + TRACE("%s l=%x r=%x d=%x <-- %x\n", debugstr_w(newData->name), newData->leftChild, newData->rightChild, newData->dirRootEntry, *index); + + return S_OK; } static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base, DirRef index, const DirEntry *data) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_WriteDirEntry(This->snapshot, - index, data); + TRACE("%x %s l=%x r=%x d=%x\n", index, debugstr_w(data->name), data->leftChild, data->rightChild, data->dirRootEntry); + + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + memcpy(&This->entries[index].data, data, sizeof(DirEntry)); + + if (index != This->base.storageDirEntry) + { + This->entries[index].dirty = 1; + + if (data->size.QuadPart == 0 && + This->entries[index].transactedParentEntry != DIRENTRY_NULL) + { + /* Since this entry is modified, and we aren't using its stream data, we + * no longer care about the original entry. */ + DirRef delete_ref; + delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry); + + if (delete_ref != DIRENTRY_NULL) + This->entries[delete_ref].deleted = 1; + + This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; + } + } + + return S_OK; } static HRESULT TransactedSnapshotImpl_ReadDirEntry(StorageBaseImpl *base, DirRef index, DirEntry *data) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_ReadDirEntry(This->snapshot, - index, data); + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + memcpy(data, &This->entries[index].data, sizeof(DirEntry)); + + TRACE("%x %s l=%x r=%x d=%x\n", index, debugstr_w(data->name), data->leftChild, data->rightChild, data->dirRootEntry); + + return S_OK; } static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, @@ -4226,8 +4687,21 @@ static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; - return StorageBaseImpl_DestroyDirEntry(This->snapshot, - index); + if (This->entries[index].transactedParentEntry == DIRENTRY_NULL || + This->entries[index].data.size.QuadPart != 0) + { + /* If we deleted this entry while it has stream data. We must have left the + * data because some other entry is using it, and we need to leave the + * original entry alone. */ + memset(&This->entries[index], 0, sizeof(TransactedDirEntry)); + This->firstFreeEntry = min(index, This->firstFreeEntry); + } + else + { + This->entries[index].deleted = 1; + } + + return S_OK; } static HRESULT TransactedSnapshotImpl_StreamReadAt(StorageBaseImpl *base, @@ -4235,26 +4709,122 @@ static HRESULT TransactedSnapshotImpl_StreamReadAt(StorageBaseImpl *base, { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; - return StorageBaseImpl_StreamReadAt(This->snapshot, - index, offset, size, buffer, bytesRead); + if (This->entries[index].stream_dirty) + { + return StorageBaseImpl_StreamReadAt(This->scratch, + This->entries[index].stream_entry, offset, size, buffer, bytesRead); + } + else if (This->entries[index].transactedParentEntry == DIRENTRY_NULL) + { + /* This stream doesn't live in the parent, and we haven't allocated storage + * for it yet */ + *bytesRead = 0; + return S_OK; + } + else + { + return StorageBaseImpl_StreamReadAt(This->transactedParent, + This->entries[index].transactedParentEntry, offset, size, buffer, bytesRead); + } } static HRESULT TransactedSnapshotImpl_StreamWriteAt(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_StreamWriteAt(This->snapshot, - index, offset, size, buffer, bytesWritten); + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + hr = TransactedSnapshotImpl_MakeStreamDirty(This, index); + if (FAILED(hr)) return hr; + + hr = StorageBaseImpl_StreamWriteAt(This->scratch, + This->entries[index].stream_entry, offset, size, buffer, bytesWritten); + + if (SUCCEEDED(hr) && size != 0) + This->entries[index].data.size.QuadPart = max( + This->entries[index].data.size.QuadPart, + offset.QuadPart + size); + + return hr; } static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base, DirRef index, ULARGE_INTEGER newsize) { TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; - return StorageBaseImpl_StreamSetSize(This->snapshot, - index, newsize); + hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); + if (FAILED(hr)) return hr; + + if (This->entries[index].data.size.QuadPart == newsize.QuadPart) + return S_OK; + + if (newsize.QuadPart == 0) + { + /* Destroy any parent references or entries in the scratch file. */ + if (This->entries[index].stream_dirty) + { + ULARGE_INTEGER zero; + zero.QuadPart = 0; + StorageBaseImpl_StreamSetSize(This->scratch, + This->entries[index].stream_entry, zero); + StorageBaseImpl_DestroyDirEntry(This->scratch, + This->entries[index].stream_entry); + This->entries[index].stream_dirty = 0; + } + else if (This->entries[index].transactedParentEntry != DIRENTRY_NULL) + { + DirRef delete_ref; + delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry); + + if (delete_ref != DIRENTRY_NULL) + This->entries[delete_ref].deleted = 1; + + This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; + } + } + else + { + hr = TransactedSnapshotImpl_MakeStreamDirty(This, index); + if (FAILED(hr)) return hr; + + hr = StorageBaseImpl_StreamSetSize(This->scratch, + This->entries[index].stream_entry, newsize); + } + + if (SUCCEEDED(hr)) + This->entries[index].data.size = newsize; + + return hr; +} + +static HRESULT TransactedSnapshotImpl_StreamLink(StorageBaseImpl *base, + DirRef dst, DirRef src) +{ + TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) base; + HRESULT hr; + TransactedDirEntry *dst_entry, *src_entry; + + hr = TransactedSnapshotImpl_EnsureReadEntry(This, src); + if (FAILED(hr)) return hr; + + hr = TransactedSnapshotImpl_EnsureReadEntry(This, dst); + if (FAILED(hr)) return hr; + + dst_entry = &This->entries[dst]; + src_entry = &This->entries[src]; + + dst_entry->stream_dirty = src_entry->stream_dirty; + dst_entry->stream_entry = src_entry->stream_entry; + dst_entry->transactedParentEntry = src_entry->transactedParentEntry; + dst_entry->newTransactedParentEntry = src_entry->newTransactedParentEntry; + dst_entry->data.size = src_entry->data.size; + + return S_OK; } static const IStorageVtbl TransactedSnapshotImpl_Vtbl = @@ -4289,7 +4859,8 @@ static const StorageBaseImplVtbl TransactedSnapshotImpl_BaseVtbl = TransactedSnapshotImpl_DestroyDirEntry, TransactedSnapshotImpl_StreamReadAt, TransactedSnapshotImpl_StreamWriteAt, - TransactedSnapshotImpl_StreamSetSize + TransactedSnapshotImpl_StreamSetSize, + TransactedSnapshotImpl_StreamLink }; static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage, @@ -4317,17 +4888,35 @@ static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage, (*result)->base.filename = parentStorage->filename; - /* Create a new temporary storage to act as the snapshot */ - hr = CreateSnapshotFile(parentStorage, &(*result)->snapshot); + /* Create a new temporary storage to act as the scratch file. */ + hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, + 0, (IStorage**)&(*result)->scratch); if (SUCCEEDED(hr)) { - (*result)->base.storageDirEntry = (*result)->snapshot->storageDirEntry; + ULONG num_entries = 20; - /* parentStorage already has 1 reference, which we take over here. */ - (*result)->transactedParent = parentStorage; + (*result)->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TransactedDirEntry) * num_entries); - parentStorage->transactedChild = (StorageBaseImpl*)*result; + (*result)->entries_size = num_entries; + + (*result)->firstFreeEntry = 0; + + if ((*result)->entries) + { + /* parentStorage already has 1 reference, which we take over here. */ + (*result)->transactedParent = parentStorage; + + parentStorage->transactedChild = (StorageBaseImpl*)*result; + + (*result)->base.storageDirEntry = TransactedSnapshotImpl_CreateStubEntry(*result, parentStorage->storageDirEntry); + } + else + { + IStorage_Release((IStorage*)(*result)->scratch); + + hr = E_OUTOFMEMORY; + } } if (FAILED(hr)) HeapFree(GetProcessHeap(), 0, (*result)); @@ -4474,6 +5063,15 @@ static HRESULT StorageInternalImpl_StreamSetSize(StorageBaseImpl *base, index, newsize); } +static HRESULT StorageInternalImpl_StreamLink(StorageBaseImpl *base, + DirRef dst, DirRef src) +{ + StorageInternalImpl* This = (StorageInternalImpl*) base; + + return StorageBaseImpl_StreamLink(This->parentStorage, + dst, src); +} + /****************************************************************************** ** ** Storage32InternalImpl_Commit @@ -4833,7 +5431,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl = StorageInternalImpl_DestroyDirEntry, StorageInternalImpl_StreamReadAt, StorageInternalImpl_StreamWriteAt, - StorageInternalImpl_StreamSetSize + StorageInternalImpl_StreamSetSize, + StorageInternalImpl_StreamLink }; /****************************************************************************** @@ -5026,38 +5625,134 @@ void StorageUtl_CopyDirEntryToSTATSTG( ** BlockChainStream implementation */ +/* Read and save the index of all blocks in this stream. */ +HRESULT BlockChainStream_UpdateIndexCache(BlockChainStream* This) +{ + ULONG next_sector, next_offset; + HRESULT hr; + struct BlockChainRun *last_run; + + if (This->indexCacheLen == 0) + { + last_run = NULL; + next_offset = 0; + next_sector = BlockChainStream_GetHeadOfChain(This); + } + else + { + last_run = &This->indexCache[This->indexCacheLen-1]; + next_offset = last_run->lastOffset+1; + hr = StorageImpl_GetNextBlockInChain(This->parentStorage, + last_run->firstSector + last_run->lastOffset - last_run->firstOffset, + &next_sector); + if (FAILED(hr)) return hr; + } + + while (next_sector != BLOCK_END_OF_CHAIN) + { + if (!last_run || next_sector != last_run->firstSector + next_offset - last_run->firstOffset) + { + /* Add the current block to the cache. */ + if (This->indexCacheSize == 0) + { + This->indexCache = HeapAlloc(GetProcessHeap(), 0, sizeof(struct BlockChainRun)*16); + if (!This->indexCache) return E_OUTOFMEMORY; + This->indexCacheSize = 16; + } + else if (This->indexCacheSize == This->indexCacheLen) + { + struct BlockChainRun *new_cache; + ULONG new_size; + + new_size = This->indexCacheSize * 2; + new_cache = HeapAlloc(GetProcessHeap(), 0, sizeof(struct BlockChainRun)*new_size); + if (!new_cache) return E_OUTOFMEMORY; + memcpy(new_cache, This->indexCache, sizeof(struct BlockChainRun)*This->indexCacheLen); + + HeapFree(GetProcessHeap(), 0, This->indexCache); + This->indexCache = new_cache; + This->indexCacheSize = new_size; + } + + This->indexCacheLen++; + last_run = &This->indexCache[This->indexCacheLen-1]; + last_run->firstSector = next_sector; + last_run->firstOffset = next_offset; + } + + last_run->lastOffset = next_offset; + + /* Find the next block. */ + next_offset++; + hr = StorageImpl_GetNextBlockInChain(This->parentStorage, next_sector, &next_sector); + if (FAILED(hr)) return hr; + } + + if (This->indexCacheLen) + { + This->tailIndex = last_run->firstSector + last_run->lastOffset - last_run->firstOffset; + This->numBlocks = last_run->lastOffset+1; + } + else + { + This->tailIndex = BLOCK_END_OF_CHAIN; + This->numBlocks = 0; + } + + return S_OK; +} + +/* Locate the nth block in this stream. */ +ULONG BlockChainStream_GetSectorOfOffset(BlockChainStream *This, ULONG offset) +{ + ULONG min_offset = 0, max_offset = This->numBlocks-1; + ULONG min_run = 0, max_run = This->indexCacheLen-1; + + if (offset >= This->numBlocks) + return BLOCK_END_OF_CHAIN; + + while (min_run < max_run) + { + ULONG run_to_check = min_run + (offset - min_offset) * (max_run - min_run) / (max_offset - min_offset); + if (offset < This->indexCache[run_to_check].firstOffset) + { + max_offset = This->indexCache[run_to_check].firstOffset-1; + max_run = run_to_check-1; + } + else if (offset > This->indexCache[run_to_check].lastOffset) + { + min_offset = This->indexCache[run_to_check].lastOffset+1; + min_run = run_to_check+1; + } + else + /* Block is in this run. */ + min_run = max_run = run_to_check; + } + + return This->indexCache[min_run].firstSector + offset - This->indexCache[min_run].firstOffset; +} + BlockChainStream* BlockChainStream_Construct( StorageImpl* parentStorage, ULONG* headOfStreamPlaceHolder, DirRef dirEntry) { BlockChainStream* newStream; - ULONG blockIndex; newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream)); newStream->parentStorage = parentStorage; newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; newStream->ownerDirEntry = dirEntry; - newStream->lastBlockNoInSequence = 0xFFFFFFFF; - newStream->tailIndex = BLOCK_END_OF_CHAIN; - newStream->numBlocks = 0; + newStream->indexCache = NULL; + newStream->indexCacheLen = 0; + newStream->indexCacheSize = 0; - blockIndex = BlockChainStream_GetHeadOfChain(newStream); - - while (blockIndex != BLOCK_END_OF_CHAIN) + if (FAILED(BlockChainStream_UpdateIndexCache(newStream))) { - newStream->numBlocks++; - newStream->tailIndex = blockIndex; - - if(FAILED(StorageImpl_GetNextBlockInChain( - parentStorage, - blockIndex, - &blockIndex))) - { - HeapFree(GetProcessHeap(), 0, newStream); - return NULL; - } + HeapFree(GetProcessHeap(), 0, newStream->indexCache); + HeapFree(GetProcessHeap(), 0, newStream); + return NULL; } return newStream; @@ -5065,6 +5760,8 @@ BlockChainStream* BlockChainStream_Construct( void BlockChainStream_Destroy(BlockChainStream* This) { + if (This) + HeapFree(GetProcessHeap(), 0, This->indexCache); HeapFree(GetProcessHeap(), 0, This); } @@ -5105,27 +5802,10 @@ static ULONG BlockChainStream_GetHeadOfChain(BlockChainStream* This) * * Returns the number of blocks that comprises this chain. * This is not the size of the stream as the last block may not be full! - * */ static ULONG BlockChainStream_GetCount(BlockChainStream* This) { - ULONG blockIndex; - ULONG count = 0; - - blockIndex = BlockChainStream_GetHeadOfChain(This); - - while (blockIndex != BLOCK_END_OF_CHAIN) - { - count++; - - if(FAILED(StorageImpl_GetNextBlockInChain( - This->parentStorage, - blockIndex, - &blockIndex))) - return 0; - } - - return count; + return This->numBlocks; } /****************************************************************************** @@ -5146,44 +5826,26 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This, ULONG bytesToReadInBuffer; ULONG blockIndex; BYTE* bufferWalker; + ULARGE_INTEGER stream_size; TRACE("(%p)-> %i %p %i %p\n",This, offset.u.LowPart, buffer, size, bytesRead); /* * Find the first block in the stream that contains part of the buffer. */ - if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) || - (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) || - (blockNoInSequence < This->lastBlockNoInSequence) ) - { - blockIndex = BlockChainStream_GetHeadOfChain(This); - This->lastBlockNoInSequence = blockNoInSequence; - } + blockIndex = BlockChainStream_GetSectorOfOffset(This, blockNoInSequence); + + *bytesRead = 0; + + stream_size = BlockChainStream_GetSize(This); + if (stream_size.QuadPart > offset.QuadPart) + size = min(stream_size.QuadPart - offset.QuadPart, size); else - { - ULONG temp = blockNoInSequence; - - blockIndex = This->lastBlockNoInSequenceIndex; - blockNoInSequence -= This->lastBlockNoInSequence; - This->lastBlockNoInSequence = temp; - } - - while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) - { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex))) - return STG_E_DOCFILECORRUPT; - blockNoInSequence--; - } - - if ((blockNoInSequence > 0) && (blockIndex == BLOCK_END_OF_CHAIN)) - return STG_E_DOCFILECORRUPT; /* We failed to find the starting block */ - - This->lastBlockNoInSequenceIndex = blockIndex; + return S_OK; /* * Start reading the buffer. */ - *bytesRead = 0; bufferWalker = buffer; while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) @@ -5221,7 +5883,7 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This, break; } - return (size == 0) ? S_OK : STG_E_READFAULT; + return S_OK; } /****************************************************************************** @@ -5245,31 +5907,7 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This, /* * Find the first block in the stream that contains part of the buffer. */ - if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) || - (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) || - (blockNoInSequence < This->lastBlockNoInSequence) ) - { - blockIndex = BlockChainStream_GetHeadOfChain(This); - This->lastBlockNoInSequence = blockNoInSequence; - } - else - { - ULONG temp = blockNoInSequence; - - blockIndex = This->lastBlockNoInSequenceIndex; - blockNoInSequence -= This->lastBlockNoInSequence; - This->lastBlockNoInSequence = temp; - } - - while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) - { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, - &blockIndex))) - return STG_E_DOCFILECORRUPT; - blockNoInSequence--; - } - - This->lastBlockNoInSequenceIndex = blockIndex; + blockIndex = BlockChainStream_GetSectorOfOffset(This, blockNoInSequence); /* BlockChainStream_SetSize should have already been called to ensure we have * enough blocks in the chain to write into */ @@ -5330,15 +5968,8 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This, static BOOL BlockChainStream_Shrink(BlockChainStream* This, ULARGE_INTEGER newSize) { - ULONG blockIndex, extraBlock; + ULONG blockIndex; ULONG numBlocks; - ULONG count = 1; - - /* - * Reset the last accessed block cache. - */ - This->lastBlockNoInSequence = 0xFFFFFFFF; - This->lastBlockNoInSequenceIndex = BLOCK_END_OF_CHAIN; /* * Figure out how many blocks are needed to contain the new size @@ -5348,43 +5979,62 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This, if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0) numBlocks++; - blockIndex = BlockChainStream_GetHeadOfChain(This); - - /* - * Go to the new end of chain - */ - while (count < numBlocks) + if (numBlocks) { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, - &blockIndex))) - return FALSE; - count++; + /* + * Go to the new end of chain + */ + blockIndex = BlockChainStream_GetSectorOfOffset(This, numBlocks-1); + + /* Mark the new end of chain */ + StorageImpl_SetNextBlockInChain( + This->parentStorage, + blockIndex, + BLOCK_END_OF_CHAIN); + + This->tailIndex = blockIndex; + } + else + { + if (This->headOfStreamPlaceHolder != 0) + { + *This->headOfStreamPlaceHolder = BLOCK_END_OF_CHAIN; + } + else + { + DirEntry chainEntry; + assert(This->ownerDirEntry != DIRENTRY_NULL); + + StorageImpl_ReadDirEntry( + This->parentStorage, + This->ownerDirEntry, + &chainEntry); + + chainEntry.startingBlock = BLOCK_END_OF_CHAIN; + + StorageImpl_WriteDirEntry( + This->parentStorage, + This->ownerDirEntry, + &chainEntry); + } + + This->tailIndex = BLOCK_END_OF_CHAIN; } - /* Get the next block before marking the new end */ - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, - &extraBlock))) - return FALSE; - - /* Mark the new end of chain */ - StorageImpl_SetNextBlockInChain( - This->parentStorage, - blockIndex, - BLOCK_END_OF_CHAIN); - - This->tailIndex = blockIndex; This->numBlocks = numBlocks; /* * Mark the extra blocks as free */ - while (extraBlock != BLOCK_END_OF_CHAIN) + while (This->indexCacheLen && This->indexCache[This->indexCacheLen-1].lastOffset >= numBlocks) { - if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock, - &blockIndex))) - return FALSE; - StorageImpl_FreeBigBlock(This->parentStorage, extraBlock); - extraBlock = blockIndex; + struct BlockChainRun *last_run = &This->indexCache[This->indexCacheLen-1]; + StorageImpl_FreeBigBlock(This->parentStorage, + last_run->firstSector + last_run->lastOffset - last_run->firstOffset); + if (last_run->lastOffset == last_run->firstOffset) + This->indexCacheLen--; + else + last_run->lastOffset--; } return TRUE; @@ -5498,6 +6148,9 @@ static BOOL BlockChainStream_Enlarge(BlockChainStream* This, This->numBlocks = newNumBlocks; } + if (FAILED(BlockChainStream_UpdateIndexCache(This))) + return FALSE; + return TRUE; } @@ -5663,6 +6316,9 @@ static HRESULT SmallBlockChainStream_GetNextBlockInChain( &buffer, &bytesRead); + if (SUCCEEDED(res) && bytesRead != sizeof(DWORD)) + res = STG_E_READFAULT; + if (SUCCEEDED(res)) { StorageUtl_ReadDWord((BYTE *)&buffer, 0, nextBlockInChain); @@ -5734,6 +6390,9 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( ULONG nextBlockIndex = BLOCK_END_OF_CHAIN; HRESULT res = S_OK; ULONG smallBlocksPerBigBlock; + DirEntry rootEntry; + ULONG blocksRequired; + ULARGE_INTEGER old_size, size_required; offsetOfBlockInDepot.u.HighPart = 0; @@ -5754,7 +6413,7 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( /* * If we run out of space for the small block depot, enlarge it */ - if (SUCCEEDED(res)) + if (SUCCEEDED(res) && bytesRead == sizeof(DWORD)) { StorageUtl_ReadDWord((BYTE *)&buffer, 0, &nextBlockIndex); @@ -5766,76 +6425,22 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( ULONG count = BlockChainStream_GetCount(This->parentStorage->smallBlockDepotChain); - ULONG sbdIndex = This->parentStorage->smallBlockDepotStart; - ULONG nextBlock, newsbdIndex; BYTE smallBlockDepot[MAX_BIG_BLOCK_SIZE]; + ULARGE_INTEGER newSize, offset; + ULONG bytesWritten; - nextBlock = sbdIndex; - while (nextBlock != BLOCK_END_OF_CHAIN) - { - sbdIndex = nextBlock; - StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex, &nextBlock); - } - - newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); - if (sbdIndex != BLOCK_END_OF_CHAIN) - StorageImpl_SetNextBlockInChain( - This->parentStorage, - sbdIndex, - newsbdIndex); - - StorageImpl_SetNextBlockInChain( - This->parentStorage, - newsbdIndex, - BLOCK_END_OF_CHAIN); + newSize.QuadPart = (count + 1) * This->parentStorage->bigBlockSize; + BlockChainStream_Enlarge(This->parentStorage->smallBlockDepotChain, newSize); /* * Initialize all the small blocks to free */ memset(smallBlockDepot, BLOCK_UNUSED, This->parentStorage->bigBlockSize); - StorageImpl_WriteBigBlock(This->parentStorage, newsbdIndex, smallBlockDepot); + offset.QuadPart = count * This->parentStorage->bigBlockSize; + BlockChainStream_WriteAt(This->parentStorage->smallBlockDepotChain, + offset, This->parentStorage->bigBlockSize, smallBlockDepot, &bytesWritten); - if (count == 0) - { - /* - * We have just created the small block depot. - */ - DirEntry rootEntry; - ULONG sbStartIndex; - - /* - * Save it in the header - */ - This->parentStorage->smallBlockDepotStart = newsbdIndex; - StorageImpl_SaveFileHeader(This->parentStorage); - - /* - * And allocate the first big block that will contain small blocks - */ - sbStartIndex = - StorageImpl_GetNextFreeBigBlock(This->parentStorage); - - StorageImpl_SetNextBlockInChain( - This->parentStorage, - sbStartIndex, - BLOCK_END_OF_CHAIN); - - StorageImpl_ReadDirEntry( - This->parentStorage, - This->parentStorage->base.storageDirEntry, - &rootEntry); - - rootEntry.startingBlock = sbStartIndex; - rootEntry.size.u.HighPart = 0; - rootEntry.size.u.LowPart = This->parentStorage->bigBlockSize; - - StorageImpl_WriteDirEntry( - This->parentStorage, - This->parentStorage->base.storageDirEntry, - &rootEntry); - } - else - StorageImpl_SaveFileHeader(This->parentStorage); + StorageImpl_SaveFileHeader(This->parentStorage); } } @@ -5847,30 +6452,29 @@ static ULONG SmallBlockChainStream_GetNextFreeBlock( /* * Verify if we have to allocate big blocks to contain small blocks */ - if (blockIndex % smallBlocksPerBigBlock == 0) + blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1; + + size_required.QuadPart = blocksRequired * This->parentStorage->bigBlockSize; + + old_size = BlockChainStream_GetSize(This->parentStorage->smallBlockRootChain); + + if (size_required.QuadPart > old_size.QuadPart) { - DirEntry rootEntry; - ULONG blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1; + BlockChainStream_SetSize( + This->parentStorage->smallBlockRootChain, + size_required); StorageImpl_ReadDirEntry( This->parentStorage, This->parentStorage->base.storageDirEntry, &rootEntry); - if (rootEntry.size.u.LowPart < - (blocksRequired * This->parentStorage->bigBlockSize)) - { - rootEntry.size.u.LowPart += This->parentStorage->bigBlockSize; + rootEntry.size = size_required; - BlockChainStream_SetSize( - This->parentStorage->smallBlockRootChain, - rootEntry.size); - - StorageImpl_WriteDirEntry( - This->parentStorage, - This->parentStorage->base.storageDirEntry, - &rootEntry); - } + StorageImpl_WriteDirEntry( + This->parentStorage, + This->parentStorage->base.storageDirEntry, + &rootEntry); } return blockIndex; @@ -5900,12 +6504,21 @@ HRESULT SmallBlockChainStream_ReadAt( ULONG blockIndex; ULONG bytesReadFromBigBlockFile; BYTE* bufferWalker; + ULARGE_INTEGER stream_size; /* * This should never happen on a small block file. */ assert(offset.u.HighPart==0); + *bytesRead = 0; + + stream_size = SmallBlockChainStream_GetSize(This); + if (stream_size.QuadPart > offset.QuadPart) + size = min(stream_size.QuadPart - offset.QuadPart, size); + else + return S_OK; + /* * Find the first block in the stream that contains part of the buffer. */ @@ -5922,7 +6535,6 @@ HRESULT SmallBlockChainStream_ReadAt( /* * Start reading the buffer. */ - *bytesRead = 0; bufferWalker = buffer; while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) @@ -5956,6 +6568,9 @@ HRESULT SmallBlockChainStream_ReadAt( if (FAILED(rc)) return rc; + if (!bytesReadFromBigBlockFile) + return STG_E_DOCFILECORRUPT; + /* * Step to the next big block. */ @@ -5969,7 +6584,7 @@ HRESULT SmallBlockChainStream_ReadAt( offsetInBlock = (offsetInBlock + bytesReadFromBigBlockFile) % This->parentStorage->smallBlockSize; } - return (size == 0) ? S_OK : STG_E_READFAULT; + return S_OK; } /****************************************************************************** diff --git a/dll/win32/ole32/storage32.h b/dll/win32/ole32/storage32.h index 36a7d679af6..19f3f2d682c 100644 --- a/dll/win32/ole32/storage32.h +++ b/dll/win32/ole32/storage32.h @@ -263,6 +263,7 @@ struct StorageBaseImplVtbl { HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); + HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef); }; static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) @@ -320,6 +321,16 @@ static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, return This->baseVtbl->StreamSetSize(This, index, newsize); } +/* Make dst point to the same stream that src points to. Other stream operations + * will not work properly for entries that point to the same stream, so this + * must be a very temporary state, and only one entry pointing to a given stream + * may be reachable at any given time. */ +static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This, + DirRef dst, DirRef src) +{ + return This->baseVtbl->StreamLink(This, dst, src); +} + /**************************************************************************** * StorageBaseImpl stream list handlers */ @@ -513,13 +524,22 @@ void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destinat * The BlockChainStream class is a utility class that is used to create an * abstraction of the big block chains in the storage file. */ +struct BlockChainRun +{ + /* This represents a range of blocks that happen reside in consecutive sectors. */ + ULONG firstSector; + ULONG firstOffset; + ULONG lastOffset; +}; + struct BlockChainStream { StorageImpl* parentStorage; ULONG* headOfStreamPlaceHolder; DirRef ownerDirEntry; - ULONG lastBlockNoInSequence; - ULONG lastBlockNoInSequenceIndex; + struct BlockChainRun* indexCache; + ULONG indexCacheLen; + ULONG indexCacheSize; ULONG tailIndex; ULONG numBlocks; }; diff --git a/dll/win32/ole32/usrmarshal.c b/dll/win32/ole32/usrmarshal.c index ed316201f69..2d238e6ccc3 100644 --- a/dll/win32/ole32/usrmarshal.c +++ b/dll/win32/ole32/usrmarshal.c @@ -2761,7 +2761,8 @@ void CALLBACK IAdviseSink_OnDataChange_Proxy( FORMATETC *pFormatetc, STGMEDIUM *pStgmed) { - FIXME(":stub\n"); + TRACE("(%p)->(%p, %p)\n", This, pFormatetc, pStgmed); + IAdviseSink_RemoteOnDataChange_Proxy(This, pFormatetc, pStgmed); } HRESULT __RPC_STUB IAdviseSink_OnDataChange_Stub( @@ -2769,8 +2770,9 @@ HRESULT __RPC_STUB IAdviseSink_OnDataChange_Stub( FORMATETC *pFormatetc, ASYNC_STGMEDIUM *pStgmed) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%p, %p)\n", This, pFormatetc, pStgmed); + IAdviseSink_OnDataChange(This, pFormatetc, pStgmed); + return S_OK; } void CALLBACK IAdviseSink_OnViewChange_Proxy( @@ -2778,7 +2780,8 @@ void CALLBACK IAdviseSink_OnViewChange_Proxy( DWORD dwAspect, LONG lindex) { - FIXME(":stub\n"); + TRACE("(%p)->(%d, %d)\n", This, dwAspect, lindex); + IAdviseSink_RemoteOnViewChange_Proxy(This, dwAspect, lindex); } HRESULT __RPC_STUB IAdviseSink_OnViewChange_Stub( @@ -2786,64 +2789,73 @@ HRESULT __RPC_STUB IAdviseSink_OnViewChange_Stub( DWORD dwAspect, LONG lindex) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%d, %d)\n", This, dwAspect, lindex); + IAdviseSink_OnViewChange(This, dwAspect, lindex); + return S_OK; } void CALLBACK IAdviseSink_OnRename_Proxy( IAdviseSink* This, IMoniker *pmk) { - FIXME(":stub\n"); + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink_RemoteOnRename_Proxy(This, pmk); } HRESULT __RPC_STUB IAdviseSink_OnRename_Stub( IAdviseSink* This, IMoniker *pmk) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink_OnRename(This, pmk); + return S_OK; } void CALLBACK IAdviseSink_OnSave_Proxy( IAdviseSink* This) { - FIXME(":stub\n"); + TRACE("(%p)\n", This); + IAdviseSink_RemoteOnSave_Proxy(This); } HRESULT __RPC_STUB IAdviseSink_OnSave_Stub( IAdviseSink* This) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)\n", This); + IAdviseSink_OnSave(This); + return S_OK; } void CALLBACK IAdviseSink_OnClose_Proxy( IAdviseSink* This) { - FIXME(":stub\n"); + TRACE("(%p)\n", This); + IAdviseSink_RemoteOnClose_Proxy(This); } HRESULT __RPC_STUB IAdviseSink_OnClose_Stub( IAdviseSink* This) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)\n", This); + IAdviseSink_OnClose(This); + return S_OK; } void CALLBACK IAdviseSink2_OnLinkSrcChange_Proxy( IAdviseSink2* This, IMoniker *pmk) { - FIXME(":stub\n"); + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink2_RemoteOnLinkSrcChange_Proxy(This, pmk); } HRESULT __RPC_STUB IAdviseSink2_OnLinkSrcChange_Stub( IAdviseSink2* This, IMoniker *pmk) { - FIXME(":stub\n"); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pmk); + IAdviseSink2_OnLinkSrcChange(This, pmk); + return S_OK; } HRESULT CALLBACK IDataObject_GetData_Proxy( diff --git a/dll/win32/riched20/riched20.rbuild b/dll/win32/riched20/riched20.rbuild index 0191c64390a..b176049bb8a 100644 --- a/dll/win32/riched20/riched20.rbuild +++ b/dll/win32/riched20/riched20.rbuild @@ -1,7 +1,7 @@ - + . include/reactos/wine diff --git a/dll/win32/rsaenh/implglue.c b/dll/win32/rsaenh/implglue.c index 7ecfc289ecf..c217007221c 100644 --- a/dll/win32/rsaenh/implglue.c +++ b/dll/win32/rsaenh/implglue.c @@ -342,6 +342,7 @@ BOOL encrypt_block_impl(ALG_ID aiAlgid, DWORD dwKeySpec, KEY_CONTEXT *pKeyContex case CALG_RSA_KEYX: case CALG_RSA_SIGN: + case CALG_SSL3_SHAMD5: outlen = inlen = (mp_count_bits(&pKeyContext->rsa.N)+7)/8; if (enc) { if (rsa_exptmod(in, inlen, out, &outlen, dwKeySpec, &pKeyContext->rsa) != CRYPT_OK) { diff --git a/dll/win32/rsaenh/rsaenh.c b/dll/win32/rsaenh/rsaenh.c index 8a5be9935c3..d7d63b13676 100644 --- a/dll/win32/rsaenh/rsaenh.c +++ b/dll/win32/rsaenh/rsaenh.c @@ -1167,16 +1167,6 @@ static void store_key_container_keys(KEYCONTAINER *pKeyContainer) static void store_key_container_permissions(KEYCONTAINER *pKeyContainer) { HKEY hKey; - DWORD dwFlags; - - /* On WinXP, persistent keys are stored in a file located at: - * $AppData$\\Microsoft\\Crypto\\RSA\\$SID$\\some_hex_string - */ - - if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) - dwFlags = CRYPTPROTECT_LOCAL_MACHINE; - else - dwFlags = 0; if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) { @@ -1426,7 +1416,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, ALG_ID aiAlgid; DWORD dwLen; CONST BYTE abOID[19]; - } aOIDDescriptor[8] = { + } aOIDDescriptor[] = { { CALG_MD2, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 } }, { CALG_MD4, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, @@ -1444,6 +1434,7 @@ static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, { CALG_SHA_384, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x40 } }, + { CALG_SSL3_SHAMD5, 0, { 0 } }, { 0, 0, { 0 } } }; DWORD dwIdxOID, i, j; diff --git a/dll/win32/shdocvw/iexplore.c b/dll/win32/shdocvw/iexplore.c index d65810f58f9..9c14cfc1631 100644 --- a/dll/win32/shdocvw/iexplore.c +++ b/dll/win32/shdocvw/iexplore.c @@ -37,6 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); +#define IDI_APPICON 101 + static const WCHAR szIEWinFrame[] = { 'I','E','F','r','a','m','e',0 }; static LRESULT iewnd_OnCreate(HWND hwnd, LPCREATESTRUCTW lpcs) @@ -85,7 +87,7 @@ ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) void register_iewindow_class(void) { - WNDCLASSW wc; + WNDCLASSEXW wc; memset(&wc, 0, sizeof wc); wc.style = 0; @@ -93,13 +95,15 @@ void register_iewindow_class(void) wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(InternetExplorer*); wc.hInstance = shdocvw_hinstance; - wc.hIcon = 0; - wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDI_APPLICATION)); + wc.hIcon = LoadIconW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON)); + wc.hIconSm = LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); + wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDC_ARROW)); wc.hbrBackground = 0; wc.lpszClassName = szIEWinFrame; wc.lpszMenuName = NULL; - RegisterClassW(&wc); + RegisterClassExW(&wc); } void unregister_iewindow_class(void) diff --git a/dll/win32/shdocvw/intshcut.c b/dll/win32/shdocvw/intshcut.c index b389ec3727a..32dab6dd519 100644 --- a/dll/win32/shdocvw/intshcut.c +++ b/dll/win32/shdocvw/intshcut.c @@ -74,6 +74,7 @@ static BOOL run_winemenubuilder( const WCHAR *args ) PROCESS_INFORMATION pi; BOOL ret; WCHAR app[MAX_PATH]; + void *redir; GetSystemDirectoryW( app, MAX_PATH - sizeof(menubuilder)/sizeof(WCHAR) ); strcatW( app, menubuilder ); @@ -91,7 +92,9 @@ static BOOL run_winemenubuilder( const WCHAR *args ) memset(&si, 0, sizeof(si)); si.cb = sizeof(si); + Wow64DisableWow64FsRedirection( &redir ); ret = CreateProcessW( app, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); + Wow64RevertWow64FsRedirection( redir ); heap_free( buffer ); diff --git a/dll/win32/shdocvw/navigate.c b/dll/win32/shdocvw/navigate.c index 8ba5f692740..99980c7c31b 100644 --- a/dll/win32/shdocvw/navigate.c +++ b/dll/win32/shdocvw/navigate.c @@ -642,7 +642,7 @@ static HRESULT async_doc_navigate(DocHost *This, LPCWSTR url, LPCWSTR headers, P return free_doc_navigate_task(task, TRUE); } - if(task->post_data) { + if(post_data) { task->post_data = SafeArrayCreateVector(VT_UI1, 0, post_data_size); if(!task->post_data) return free_doc_navigate_task(task, TRUE); @@ -950,7 +950,132 @@ static const IHlinkFrameVtbl HlinkFrameVtbl = { HlinkFrame_UpdateHlink }; +#define TARGETFRAME2_THIS(iface) DEFINE_THIS(WebBrowser, ITargetFrame2, iface) + +static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + return IWebBrowser2_QueryInterface(WEBBROWSER2(This), riid, ppv); +} + +static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + return IWebBrowser2_AddRef(WEBBROWSER2(This)); +} + +static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + return IWebBrowser2_Release(WEBBROWSER2(This)); +} + +static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppszFrameName); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppunkParent); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc)); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, ppContainer); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%x)\n", This, dwFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p)\n", This, pdwFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame); + return E_NOTIMPL; +} + +static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias) +{ + WebBrowser *This = TARGETFRAME2_THIS(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias); + return E_NOTIMPL; +} + +#undef TARGETFRAME2_THIS + +static const ITargetFrame2Vtbl TargetFrame2Vtbl = { + TargetFrame2_QueryInterface, + TargetFrame2_AddRef, + TargetFrame2_Release, + TargetFrame2_SetFrameName, + TargetFrame2_GetFrameName, + TargetFrame2_GetParentFrame, + TargetFrame2_SetFrameSrc, + TargetFrame2_GetFrameSrc, + TargetFrame2_GetFramesContainer, + TargetFrame2_SetFrameOptions, + TargetFrame2_GetFrameOptions, + TargetFrame2_SetFrameMargins, + TargetFrame2_GetFrameMargins, + TargetFrame2_FindFrame, + TargetFrame2_GetTargetAlias +}; + void WebBrowser_HlinkFrame_Init(WebBrowser *This) { This->lpHlinkFrameVtbl = &HlinkFrameVtbl; + This->lpITargetFrame2Vtbl = &TargetFrame2Vtbl; } diff --git a/dll/win32/shdocvw/shdocvw.h b/dll/win32/shdocvw/shdocvw.h index 1184298dca9..1af0365d25d 100644 --- a/dll/win32/shdocvw/shdocvw.h +++ b/dll/win32/shdocvw/shdocvw.h @@ -37,6 +37,7 @@ #include "exdisp.h" #include "mshtmhst.h" #include "hlink.h" +#include "htiframe.h" #include "wine/unicode.h" @@ -126,7 +127,9 @@ struct WebBrowser { const IOleInPlaceActiveObjectVtbl *lpOleInPlaceActiveObjectVtbl; const IOleCommandTargetVtbl *lpOleCommandTargetVtbl; const IHlinkFrameVtbl *lpHlinkFrameVtbl; + const ITargetFrame2Vtbl *lpITargetFrame2Vtbl; const IServiceProviderVtbl *lpServiceProviderVtbl; + const IDataObjectVtbl *lpDataObjectVtbl; LONG ref; @@ -184,6 +187,8 @@ struct InternetExplorer { #define ACTIVEOBJ(x) ((IOleInPlaceActiveObject*) &(x)->lpOleInPlaceActiveObjectVtbl) #define OLECMD(x) ((IOleCommandTarget*) &(x)->lpOleCommandTargetVtbl) #define HLINKFRAME(x) ((IHlinkFrame*) &(x)->lpHlinkFrameVtbl) +#define DATAOBJECT(x) ((IDataObject*) &(x)->lpDataObjectVtbl) +#define TARGETFRAME2(x) ((ITargetFrame2*) &(x)->lpITargetFrame2Vtbl) #define CLIENTSITE(x) ((IOleClientSite*) &(x)->lpOleClientSiteVtbl) #define INPLACESITE(x) ((IOleInPlaceSite*) &(x)->lpOleInPlaceSiteVtbl) @@ -198,6 +203,7 @@ struct InternetExplorer { void WebBrowser_OleObject_Init(WebBrowser*); void WebBrowser_ViewObject_Init(WebBrowser*); +void WebBrowser_DataObject_Init(WebBrowser*); void WebBrowser_Persist_Init(WebBrowser*); void WebBrowser_ClassInfo_Init(WebBrowser*); void WebBrowser_HlinkFrame_Init(WebBrowser*); diff --git a/dll/win32/shdocvw/shdocvw.inf b/dll/win32/shdocvw/shdocvw.inf index 932c9beaf25..f08759c5a93 100644 --- a/dll/win32/shdocvw/shdocvw.inf +++ b/dll/win32/shdocvw/shdocvw.inf @@ -149,9 +149,9 @@ HKLM,"Software\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe","Path",, [IE.Reg] -HKLM,"Software\Microsoft\Internet Explorer","Build",,"62900.2180" -HKLM,"Software\Microsoft\Internet Explorer","IVer",,"103" -HKLM,"Software\Microsoft\Internet Explorer","Version",,"6.0.2900.2180" +HKLM,"Software\Microsoft\Internet Explorer","Build",,"86001" +HKLM,"Software\Microsoft\Internet Explorer","Version",,"8.0.6001.18702" +HKLM,"Software\Microsoft\Internet Explorer","W2kVersion",,"8.0.6001.18702" [Strings] diff --git a/dll/win32/shdocvw/shdocvw.spec b/dll/win32/shdocvw/shdocvw.spec index aa5ef512b3c..4a0dd2c678a 100644 --- a/dll/win32/shdocvw/shdocvw.spec +++ b/dll/win32/shdocvw/shdocvw.spec @@ -40,7 +40,7 @@ 151 stdcall -noname URLSubRegQueryA(str str long ptr long long) 152 stub -noname CShellUIHelper_CreateInstance2 153 stub -noname IsURLChild -158 stub -noname SHRestricted2A +158 stdcall -noname SHRestricted2A(long str long) 159 stdcall -noname SHRestricted2W(long wstr long) 160 stub -noname SHIsRestricted2W 161 stub @ # CSearchAssistantOC::OnDraw diff --git a/dll/win32/shdocvw/shdocvw_main.c b/dll/win32/shdocvw/shdocvw_main.c index 746753f0ab2..5dfd2b99ddf 100644 --- a/dll/win32/shdocvw/shdocvw_main.c +++ b/dll/win32/shdocvw/shdocvw_main.c @@ -440,3 +440,24 @@ DWORD WINAPI SHRestricted2W(DWORD res, LPCWSTR url, DWORD reserved) FIXME("(%d %s %d) stub\n", res, debugstr_w(url), reserved); return 0; } + +/****************************************************************** + * SHRestricted2A (SHDOCVW.158) + * + * See SHRestricted2W + */ +DWORD WINAPI SHRestricted2A(DWORD restriction, LPCSTR url, DWORD reserved) +{ + LPWSTR urlW = NULL; + DWORD res; + + TRACE("(%d, %s, %d)\n", restriction, debugstr_a(url), reserved); + if (url) { + DWORD len = MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0); + urlW = heap_alloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, len); + } + res = SHRestricted2W(restriction, urlW, reserved); + heap_free(urlW); + return res; +} diff --git a/dll/win32/shdocvw/view.c b/dll/win32/shdocvw/view.c index d2e58579cb6..9ee7c067333 100644 --- a/dll/win32/shdocvw/view.c +++ b/dll/win32/shdocvw/view.c @@ -1,5 +1,6 @@ /* * Copyright 2005 Jacek Caban + * Copyright 2010 Ilya Shpigor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,6 +22,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); +/********************************************************************** + * Implement the IViewObject interface + */ + #define VIEWOBJ_THIS(iface) DEFINE_THIS(WebBrowser, ViewObject, iface) static HRESULT WINAPI ViewObject_QueryInterface(IViewObject2 *iface, REFIID riid, void **ppv) @@ -122,3 +127,112 @@ void WebBrowser_ViewObject_Init(WebBrowser *This) { This->lpViewObjectVtbl = &ViewObjectVtbl; } + +/********************************************************************** + * Implement the IDataObject interface + */ + +#define DATAOBJ_THIS(iface) DEFINE_THIS(WebBrowser, DataObject, iface) + +static HRESULT WINAPI DataObject_QueryInterface(LPDATAOBJECT iface, REFIID riid, LPVOID * ppvObj) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + return IWebBrowser2_QueryInterface(WEBBROWSER(This), riid, ppvObj); +} + +static ULONG WINAPI DataObject_AddRef(LPDATAOBJECT iface) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + return IWebBrowser2_AddRef(WEBBROWSER(This)); +} + +static ULONG WINAPI DataObject_Release(LPDATAOBJECT iface) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + return IWebBrowser2_Release(WEBBROWSER(This)); +} + +static HRESULT WINAPI DataObject_GetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_GetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_QueryGetData(LPDATAOBJECT iface, LPFORMATETC pformatetc) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_SetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_EnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_DAdvise(LPDATAOBJECT iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_DUnadvise(LPDATAOBJECT iface, DWORD dwConnection) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataObject_EnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise) +{ + WebBrowser *This = DATAOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static const IDataObjectVtbl DataObjectVtbl = { + DataObject_QueryInterface, + DataObject_AddRef, + DataObject_Release, + DataObject_GetData, + DataObject_GetDataHere, + DataObject_QueryGetData, + DataObject_GetCanonicalFormatEtc, + DataObject_SetData, + DataObject_EnumFormatEtc, + DataObject_DAdvise, + DataObject_DUnadvise, + DataObject_EnumDAdvise +}; + +#undef DATAOBJ_THIS + +void WebBrowser_DataObject_Init(WebBrowser *This) +{ + This->lpDataObjectVtbl = &DataObjectVtbl; +} diff --git a/dll/win32/shdocvw/webbrowser.c b/dll/win32/shdocvw/webbrowser.c index 2ac9b9985d5..0c26a83b55e 100644 --- a/dll/win32/shdocvw/webbrowser.c +++ b/dll/win32/shdocvw/webbrowser.c @@ -102,9 +102,15 @@ static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid }else if(IsEqualGUID(&IID_IHlinkFrame, riid)) { TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv); *ppv = HLINKFRAME(This); + }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) { + TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv); + *ppv = TARGETFRAME2(This); }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { *ppv = SERVPROV(This); TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); + }else if(IsEqualGUID(&IID_IDataObject, riid)) { + *ppv = DATAOBJECT(This); + TRACE("(%p)->(IID_IDataObject %p)\n", This, ppv); }else if(IsEqualGUID(&IID_IQuickActivate, riid)) { TRACE("(%p)->(IID_IQuickActivate %p) returning NULL\n", This, ppv); return E_NOINTERFACE; @@ -1132,6 +1138,7 @@ static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, voi WebBrowser_OleObject_Init(ret); WebBrowser_ViewObject_Init(ret); + WebBrowser_DataObject_Init(ret); WebBrowser_Persist_Init(ret); WebBrowser_ClassInfo_Init(ret); WebBrowser_HlinkFrame_Init(ret); diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc index 6c80a3e3ce7..dff2e85bff0 100644 --- a/dll/win32/shell32/lang/cs-CZ.rc +++ b/dll/win32/shell32/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/win32/shell32/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2010-05-06 + * UPDATED: 2010-05-25 * THANKS TO: navaraf, who translated major part of this file */ @@ -101,7 +101,7 @@ BEGIN DEFPUSHBUTTON "&Ano", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "Ano &všem", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Ne", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Storno", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 LTEXT "", IDD_MESSAGE, 40, 10, 238, 52, 0 END diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc index f26e1d4b616..c619493d3f2 100644 --- a/dll/win32/shell32/lang/es-ES.rc +++ b/dll/win32/shell32/lang/es-ES.rc @@ -376,6 +376,16 @@ BEGIN PUSHBUTTON "Cancelar", 14006, 226, 236, 50, 14 END +IDD_SH_FILE_COPY DIALOGEX 0, 0, 264, 45 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION +CAPTION "Copiando..." +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Cancelar", 14002, 195, 14, 60, 16 + CONTROL "", 14000, "MSCTLS_PROGRESS32", 0, 8, 20, 170, 10 + LTEXT "Archivo", 14001, 8, 6, 169, 10 +END + FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 294, 240 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION CAPTION "General" @@ -755,5 +765,5 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Tamańo asignado por defecto" IDS_COPY_OF "Copia de" - IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." + IDS_SHLEXEC_NOASSOC "No hay ningún programa configurado en ReactOS para abrir este tipo de archivo." END diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc index 18bafe2a6fd..824eb22a88e 100644 --- a/dll/win32/shell32/lang/it-IT.rc +++ b/dll/win32/shell32/lang/it-IT.rc @@ -374,6 +374,16 @@ BEGIN PUSHBUTTON "Annulla", 14006, 206, 236, 50, 14 END +IDD_SH_FILE_COPY DIALOGEX 0, 0, 264, 45 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION +CAPTION "Copia in corso..." +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Annulla", 14002, 195, 14, 60, 16 + CONTROL "", 14000, "MSCTLS_PROGRESS32", 0, 8, 20, 170, 10 + LTEXT "File", 14001, 8, 6, 169, 10 +END + FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 264, 256 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION CAPTION "Generale" diff --git a/dll/win32/shell32/shelllink.c b/dll/win32/shell32/shelllink.c index b2dd1cb6ff8..ae159cdcdc2 100644 --- a/dll/win32/shell32/shelllink.c +++ b/dll/win32/shell32/shelllink.c @@ -2828,7 +2828,7 @@ ShellLink_InvokeCommand( IContextMenu* iface, LPCMINVOKECOMMANDINFO lpici ) } else if (This->sArgs != NULL) { - args = This->sArgs; + args = strdupW( This->sArgs ); } memset( &sei, 0, sizeof sei ); diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c index 332bdb67f79..22851d92010 100644 --- a/dll/win32/shlwapi/ordinal.c +++ b/dll/win32/shlwapi/ordinal.c @@ -484,7 +484,6 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen) DWORD mystrlen, mytype; DWORD len; HKEY mykey; - HRESULT retval; LCID mylcid; WCHAR *mystr; LONG lres; @@ -512,7 +511,7 @@ HRESULT WINAPI GetAcceptLanguagesW( LPWSTR langbuf, LPDWORD buflen) /* Did not find a value in the registry or the user buffer is too small */ mylcid = GetUserDefaultLCID(); - retval = LcidToRfc1766W(mylcid, mystr, mystrlen); + LcidToRfc1766W(mylcid, mystr, mystrlen); len = lstrlenW(mystr); memcpy( langbuf, mystr, min(*buflen, len+1)*sizeof(WCHAR) ); diff --git a/dll/win32/shlwapi/reg.c b/dll/win32/shlwapi/reg.c index d641955ba05..09fce55cb3f 100644 --- a/dll/win32/shlwapi/reg.c +++ b/dll/win32/shlwapi/reg.c @@ -331,8 +331,25 @@ LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags) { - FIXME("(%p, 0x%08x, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex, - debugstr_a(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + HKEY dokey; + + TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex, + pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + + if (((enumRegFlags == SHREGENUM_HKCU) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { + return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + + if (((enumRegFlags == SHREGENUM_HKLM) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { + return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + FIXME("no support for SHREGENUM_BOTH\n"); return ERROR_INVALID_FUNCTION; } @@ -345,8 +362,25 @@ LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags) { - FIXME("(%p, 0x%08x, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex, - debugstr_w(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + HKEY dokey; + + TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex, + pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); + + if (((enumRegFlags == SHREGENUM_HKCU) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { + return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + + if (((enumRegFlags == SHREGENUM_HKLM) || + (enumRegFlags == SHREGENUM_DEFAULT)) && + (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { + return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen, + NULL, pdwType, pvData, pcbData); + } + FIXME("no support for SHREGENUM_BOTH\n"); return ERROR_INVALID_FUNCTION; } diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec index 367046b5ebc..268a2e20145 100644 --- a/dll/win32/shlwapi/shlwapi.spec +++ b/dll/win32/shlwapi/shlwapi.spec @@ -683,6 +683,7 @@ @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) @ stdcall SHCreateStreamOnFileW(wstr long ptr) @ stdcall SHCreateStreamWrapper(ptr ptr long ptr) +@ stdcall SHCreateThreadRef(ptr ptr) @ stdcall SHDeleteEmptyKeyA(long ptr) @ stdcall SHDeleteEmptyKeyW(long ptr) @ stdcall SHDeleteKeyA(long str) diff --git a/dll/win32/shlwapi/string.c b/dll/win32/shlwapi/string.c index e00a92582e0..a0269b6cb37 100644 --- a/dll/win32/shlwapi/string.c +++ b/dll/win32/shlwapi/string.c @@ -1415,7 +1415,7 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, break; case STRRET_CSTR: - if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len) + if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len )) dest[len-1] = 0; break; @@ -1423,7 +1423,7 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, if (pidl) { if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, - dest, len ) && len) + dest, len )) dest[len-1] = 0; } break; diff --git a/dll/win32/shlwapi/thread.c b/dll/win32/shlwapi/thread.c index cfe6615cd69..00d26f78eb7 100644 --- a/dll/win32/shlwapi/thread.c +++ b/dll/win32/shlwapi/thread.c @@ -120,6 +120,93 @@ typedef struct tagSHLWAPI_THREAD_INFO IUnknown *refIE; /* Reference to the IE process */ } SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO; +typedef struct +{ + const IUnknownVtbl* lpVtbl; + LONG *ref; +} threadref; + +static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) +{ + threadref * This = (threadref *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObj); + + if (ppvObj == NULL) + return E_POINTER; + + if (IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObj); + *ppvObj = This; + IUnknown_AddRef((IUnknown*)*ppvObj); + return S_OK; + } + + *ppvObj = NULL; + FIXME("(%p, %s, %p) interface not supported\n", This, debugstr_guid(riid), ppvObj); + return E_NOINTERFACE; +} + +static ULONG WINAPI threadref_AddRef(IUnknown *iface) +{ + threadref * This = (threadref *)iface; + + TRACE("(%p)\n", This); + return InterlockedIncrement(This->ref); +} + +static ULONG WINAPI threadref_Release(IUnknown *iface) +{ + LONG refcount; + threadref * This = (threadref *)iface; + + TRACE("(%p)\n", This); + + refcount = InterlockedDecrement(This->ref); + if (!refcount) + HeapFree(GetProcessHeap(), 0, This); + + return refcount; +} + +/* VTable */ +static const IUnknownVtbl threadref_vt = +{ + threadref_QueryInterface, + threadref_AddRef, + threadref_Release, +}; + +/************************************************************************* + * SHCreateThreadRef [SHLWAPI.@] + * + * Create a per-thread IUnknown object + * + * PARAMS + * lprefcount [I] Pointer to a LONG to be used as refcount + * lppUnknown [O] Destination to receive the created object reference + * + * RETURNS + * Success: S_OK. lppUnknown is set to the object reference. + * Failure: E_INVALIDARG, if a parameter is NULL + */ +HRESULT WINAPI SHCreateThreadRef(LONG *lprefcount, IUnknown **lppUnknown) +{ + threadref * This; + TRACE("(%p, %p)\n", lprefcount, lppUnknown); + + if (!lprefcount || !lppUnknown) + return E_INVALIDARG; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(threadref)); + This->lpVtbl = &threadref_vt; + This->ref = lprefcount; + + *lprefcount = 1; + *lppUnknown = (IUnknown *) This; + TRACE("=> returning S_OK with %p\n", This); + return S_OK; +} /************************************************************************* * SHGetThreadRef [SHLWAPI.@] @@ -131,13 +218,13 @@ typedef struct tagSHLWAPI_THREAD_INFO * * RETURNS * Success: S_OK. lppUnknown is set to the object reference. - * Failure: E_NOINTERFACE, if an error occurs or lppUnknown is NULL. + * Failure: E_NOINTERFACE, if an error occurs or no object is set */ HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown) { TRACE("(%p)\n", lppUnknown); - if (!lppUnknown || SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) + if (SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) return E_NOINTERFACE; *lppUnknown = TlsGetValue(SHLWAPI_ThreadRef_index); @@ -159,13 +246,13 @@ HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown) * * RETURNS * Success: S_OK. lpUnknown is stored and can be retrieved by SHGetThreadRef() - * Failure: E_NOINTERFACE, if an error occurs or lpUnknown is NULL. + * Failure: E_NOINTERFACE, if an error occurs */ HRESULT WINAPI SHSetThreadRef(IUnknown *lpUnknown) { TRACE("(%p)\n", lpUnknown); - if (!lpUnknown || SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) + if (SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES) return E_NOINTERFACE; TlsSetValue(SHLWAPI_ThreadRef_index, lpUnknown); diff --git a/dll/win32/shlwapi/url.c b/dll/win32/shlwapi/url.c index cd83b457178..ad7d989a4bb 100644 --- a/dll/win32/shlwapi/url.c +++ b/dll/win32/shlwapi/url.c @@ -232,40 +232,34 @@ HRESULT WINAPI ParseURLW(LPCWSTR x, PARSEDURLW *y) HRESULT WINAPI UrlCanonicalizeA(LPCSTR pszUrl, LPSTR pszCanonicalized, LPDWORD pcchCanonicalized, DWORD dwFlags) { - LPWSTR base, canonical; + LPWSTR url, canonical; HRESULT ret; - DWORD len, len2; + DWORD len; TRACE("(%s, %p, %p, 0x%08x) *pcchCanonicalized: %d\n", debugstr_a(pszUrl), pszCanonicalized, pcchCanonicalized, dwFlags, pcchCanonicalized ? *pcchCanonicalized : -1); - if(!pszUrl || !pszCanonicalized || !pcchCanonicalized) + if(!pszUrl || !pszCanonicalized || !pcchCanonicalized || !*pcchCanonicalized) return E_INVALIDARG; - base = HeapAlloc(GetProcessHeap(), 0, - (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR)); - canonical = base + INTERNET_MAX_URL_LENGTH; - - MultiByteToWideChar(0, 0, pszUrl, -1, base, INTERNET_MAX_URL_LENGTH); - len = INTERNET_MAX_URL_LENGTH; - - ret = UrlCanonicalizeW(base, canonical, &len, dwFlags); - if (ret != S_OK) { - *pcchCanonicalized = len * 2; - HeapFree(GetProcessHeap(), 0, base); - return ret; + len = strlen(pszUrl)+1; + url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + canonical = HeapAlloc(GetProcessHeap(), 0, *pcchCanonicalized*sizeof(WCHAR)); + if(!url || !canonical) { + HeapFree(GetProcessHeap(), 0, url); + HeapFree(GetProcessHeap(), 0, canonical); + return E_OUTOFMEMORY; } - len2 = WideCharToMultiByte(0, 0, canonical, -1, 0, 0, 0, 0); - if (len2 > *pcchCanonicalized) { - *pcchCanonicalized = len2; - HeapFree(GetProcessHeap(), 0, base); - return E_POINTER; - } - WideCharToMultiByte(0, 0, canonical, -1, pszCanonicalized, *pcchCanonicalized, 0, 0); - *pcchCanonicalized = len; - HeapFree(GetProcessHeap(), 0, base); - return S_OK; + MultiByteToWideChar(0, 0, pszUrl, -1, url, len); + + ret = UrlCanonicalizeW(url, canonical, pcchCanonicalized, dwFlags); + if(ret == S_OK) + WideCharToMultiByte(0, 0, canonical, -1, pszCanonicalized, + *pcchCanonicalized+1, 0, 0); + + HeapFree(GetProcessHeap(), 0, canonical); + return ret; } /************************************************************************* @@ -287,11 +281,12 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, static const WCHAR wszFile[] = {'f','i','l','e',':'}; static const WCHAR wszRes[] = {'r','e','s',':'}; static const WCHAR wszLocalhost[] = {'l','o','c','a','l','h','o','s','t'}; + static const WCHAR wszFilePrefix[] = {'f','i','l','e',':','/','/','/'}; TRACE("(%s, %p, %p, 0x%08x) *pcchCanonicalized: %d\n", debugstr_w(pszUrl), pszCanonicalized, pcchCanonicalized, dwFlags, pcchCanonicalized ? *pcchCanonicalized : -1); - if(!pszUrl || !pszCanonicalized || !pcchCanonicalized) + if(!pszUrl || !pszCanonicalized || !pcchCanonicalized || !*pcchCanonicalized) return E_INVALIDARG; if(!*pszUrl) { @@ -300,8 +295,9 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, } nByteLen = (strlenW(pszUrl) + 1) * sizeof(WCHAR); /* length in bytes */ + /* Allocate memory for simplified URL (before escaping) */ lpszUrlCpy = HeapAlloc(GetProcessHeap(), 0, - INTERNET_MAX_URL_LENGTH * sizeof(WCHAR)); + nByteLen+sizeof(wszFilePrefix)+sizeof(WCHAR)); if((dwFlags & URL_FILE_USE_PATHURL) && nByteLen >= sizeof(wszFile) && !memcmp(wszFile, pszUrl, sizeof(wszFile))) @@ -328,8 +324,6 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, state = 0; if(pszUrl[1] == ':') { /* Assume path */ - static const WCHAR wszFilePrefix[] = {'f','i','l','e',':','/','/','/'}; - memcpy(wk2, wszFilePrefix, sizeof(wszFilePrefix)); wk2 += sizeof(wszFilePrefix)/sizeof(WCHAR); if (dwFlags & URL_FILE_USE_PATHURL) @@ -833,6 +827,8 @@ HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative, if (ret == S_OK) { /* Reuse mrelative as temp storage as its already allocated and not needed anymore */ + if(*pcchCombined == 0) + *pcchCombined = 1; ret = UrlCanonicalizeW(preliminary, mrelative, pcchCombined, (dwFlags & ~URL_FILE_USE_PATHURL)); if(SUCCEEDED(ret) && pszCombined) { lstrcpyW(pszCombined, mrelative); diff --git a/dll/win32/syssetup/lang/es-ES.rc b/dll/win32/syssetup/lang/es-ES.rc index 3b5fabc6482..878aa3b8e43 100644 --- a/dll/win32/syssetup/lang/es-ES.rc +++ b/dll/win32/syssetup/lang/es-ES.rc @@ -254,7 +254,7 @@ BEGIN IDS_SYS_ENTERTAINMENT "Entretenimiento" IDS_CMT_MPLAY32 "Ejecutar Reproductor multimedia" IDS_CMT_SNDVOL32 "Ejecutar Control de volumen" - IDS_CMT_SNDREC32 "Launch Sound Recorder" + IDS_CMT_SNDREC32 "Ejecutar Grabadora de sonidos" END STRINGTABLE @@ -292,7 +292,7 @@ BEGIN IDS_SHORT_EVENTVIEW "Visor de sucesos.lnk" IDS_SHORT_MSCONFIG "Configuración del sistema.lnk" IDS_SHORT_SNDVOL32 "Control de volumen.lnk" - IDS_SHORT_SNDREC32 "Audiorecorder.lnk" + IDS_SHORT_SNDREC32 "Grabadora de sonidos.lnk" IDS_SHORT_DXDIAG "Diagnóstico de ReactX.lnk" IDS_SHORT_PAINT "Paint.lnk" IDS_SHORT_SPIDER "Solitario Spider.lnk" diff --git a/dll/win32/urlmon/binding.c b/dll/win32/urlmon/binding.c index dcf0207278c..e0f3624ff6b 100644 --- a/dll/win32/urlmon/binding.c +++ b/dll/win32/urlmon/binding.c @@ -47,6 +47,7 @@ typedef struct { BYTE buf[1024*8]; DWORD size; BOOL init; + HANDLE file; HRESULT hres; LPWSTR cache_file; @@ -57,7 +58,7 @@ typedef struct _stgmed_obj_t stgmed_obj_t; typedef struct { void (*release)(stgmed_obj_t*); HRESULT (*fill_stgmed)(stgmed_obj_t*,STGMEDIUM*); - void *(*get_result)(stgmed_obj_t*); + HRESULT (*get_result)(stgmed_obj_t*,DWORD,void**); } stgmed_obj_vtbl; struct _stgmed_obj_t { @@ -101,6 +102,7 @@ struct Binding { LPWSTR redirect_url; IID iid; BOOL report_mime; + BOOL use_cache_file; DWORD state; HRESULT hres; download_state_t download_state; @@ -134,6 +136,20 @@ static void fill_stgmed_buffer(stgmed_buf_t *buf) buf->init = TRUE; } +static void read_protocol_data(stgmed_buf_t *stgmed_buf) +{ + BYTE buf[8192]; + DWORD read; + HRESULT hres; + + fill_stgmed_buffer(stgmed_buf); + if(stgmed_buf->size < sizeof(stgmed_buf->buf)) + return; + + do hres = IInternetProtocol_Read(stgmed_buf->protocol, buf, sizeof(buf), &read); + while(hres == S_OK); +} + static void dump_BINDINFO(BINDINFO *bi) { static const char * const BINDINFOF_str[] = { @@ -339,6 +355,19 @@ static void create_object(Binding *binding) IInternetProtocol_Terminate(binding->protocol, 0); } +static void cache_file_available(Binding *This, const WCHAR *file_name) +{ + heap_free(This->stgmed_buf->cache_file); + This->stgmed_buf->cache_file = heap_strdupW(file_name); + + if(This->use_cache_file) { + This->stgmed_buf->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(This->stgmed_buf->file == INVALID_HANDLE_VALUE) + WARN("CreateFile failed: %u\n", GetLastError()); + } +} + #define STGMEDUNK_THIS(iface) DEFINE_THIS(stgmed_buf_t, Unknown, iface) static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) @@ -377,6 +406,8 @@ static ULONG WINAPI StgMedUnk_Release(IUnknown *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + if(This->file != INVALID_HANDLE_VALUE) + CloseHandle(This->file); IInternetProtocol_Release(This->protocol); heap_free(This->cache_file); heap_free(This); @@ -403,6 +434,7 @@ static stgmed_buf_t *create_stgmed_buf(IInternetProtocol *protocol) ret->ref = 1; ret->size = 0; ret->init = FALSE; + ret->file = INVALID_HANDLE_VALUE; ret->hres = S_OK; ret->cache_file = NULL; @@ -488,6 +520,15 @@ static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv, TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead); + if(This->buf->file != INVALID_HANDLE_VALUE) { + if (!ReadFile(This->buf->file, pv, cb, &read, NULL)) + return INET_E_DOWNLOAD_FAILURE; + + if(pcbRead) + *pcbRead = read; + return read ? S_OK : S_FALSE; + } + if(This->buf->size) { read = cb; @@ -637,12 +678,13 @@ static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) return S_OK; } -static void *stgmed_stream_get_result(stgmed_obj_t *obj) +static HRESULT stgmed_stream_get_result(stgmed_obj_t *obj, DWORD bindf, void **result) { ProtocolStream *stream = (ProtocolStream*)obj; IStream_AddRef(STREAM(stream)); - return STREAM(stream); + *result = STREAM(stream); + return S_OK; } static const stgmed_obj_vtbl stgmed_stream_vtbl = { @@ -689,16 +731,7 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) return INET_E_DATA_NOT_AVAILABLE; } - fill_stgmed_buffer(file_obj->buf); - if(file_obj->buf->size == sizeof(file_obj->buf->buf)) { - BYTE buf[1024]; - DWORD read; - HRESULT hres; - - do { - hres = IInternetProtocol_Read(file_obj->buf->protocol, buf, sizeof(buf), &read); - }while(hres == S_OK); - } + read_protocol_data(file_obj->buf); stgmed->tymed = TYMED_FILE; stgmed->u.lpszFileName = file_obj->buf->cache_file; @@ -707,9 +740,9 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) return S_OK; } -static void *stgmed_file_get_result(stgmed_obj_t *obj) +static HRESULT stgmed_file_get_result(stgmed_obj_t *obj, DWORD bindf, void **result) { - return NULL; + return bindf & BINDF_ASYNCHRONOUS ? MK_S_ASYNCHRONOUS : S_OK; } static const stgmed_obj_vtbl stgmed_file_vtbl = { @@ -987,8 +1020,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink mime_available(This, szStatusText); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: - heap_free(This->stgmed_buf->cache_file); - This->stgmed_buf->cache_file = heap_strdupW(szStatusText); + cache_file_available(This, szStatusText); break; case BINDSTATUS_DECODING: IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText); @@ -1019,9 +1051,12 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres if(This->download_state == END_DOWNLOAD || (This->state & BINDING_STOPPED)) return; - if(This->download_state == BEFORE_DOWNLOAD) { + if(This->stgmed_buf->file != INVALID_HANDLE_VALUE) + read_protocol_data(This->stgmed_buf); + else if(This->download_state == BEFORE_DOWNLOAD) fill_stgmed_buffer(This->stgmed_buf); + if(This->download_state == BEFORE_DOWNLOAD) { This->download_state = DOWNLOADING; sent_begindownloaddata = TRUE; IBindStatusCallback_OnProgress(This->callback, progress, progress_max, @@ -1430,8 +1465,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, if(to_obj) ret->bindinfo.dwOptions |= 0x100000; - if(!is_urlmon_protocol(url)) + if(!(ret->bindf & BINDF_ASYNCHRONOUS)) { ret->bindf |= BINDF_NEEDFILE; + ret->use_cache_file = TRUE; + }else if(!is_urlmon_protocol(url)) { + ret->bindf |= BINDF_NEEDFILE; + } ret->url = heap_strdupW(url); @@ -1530,12 +1569,14 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED)) IInternetProtocol_UnlockRequest(binding->protocol); - *ppv = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj); + hres = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj, binding->bindf, ppv); + }else { + hres = MK_S_ASYNCHRONOUS; } IBinding_Release(BINDING(binding)); - return *ppv ? S_OK : MK_S_ASYNCHRONOUS; + return hres; } HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) diff --git a/dll/win32/urlmon/file.c b/dll/win32/urlmon/file.c index ed4802b8a3b..a517d949222 100644 --- a/dll/win32/urlmon/file.c +++ b/dll/win32/urlmon/file.c @@ -141,7 +141,10 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char); file_name = url+sizeof(wszFile)/sizeof(WCHAR); - if(file_name[0] == '/' && file_name[1] == '/') + + /* Strip both forward and back slashes */ + if( (file_name[0] == '/' && file_name[1] == '/') || + (file_name[0] == '\\' && file_name[1] == '\\')) file_name += 2; if(*file_name == '/') file_name++; diff --git a/dll/win32/urlmon/umon.c b/dll/win32/urlmon/umon.c index 5e6a8f6c21f..7ce22cc6de8 100644 --- a/dll/win32/urlmon/umon.c +++ b/dll/win32/urlmon/umon.c @@ -513,6 +513,12 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags); + if (ppmk) + *ppmk = NULL; + + if (!szURL || !ppmk) + return E_INVALIDARG; + if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n"); if(!(obj = alloc_moniker())) @@ -619,6 +625,9 @@ HRESULT WINAPI MkParseDisplayNameEx(IBindCtx *pbc, LPCWSTR szDisplayName, ULONG { TRACE("(%p %s %p %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk); + if (!pbc || !szDisplayName || !*szDisplayName || !pchEaten || !ppmk) + return E_INVALIDARG; + if(is_registered_protocol(szDisplayName)) { HRESULT hres; diff --git a/dll/win32/urlmon/uri.c b/dll/win32/urlmon/uri.c index 668aa9b7109..27b0863c2cb 100644 --- a/dll/win32/urlmon/uri.c +++ b/dll/win32/urlmon/uri.c @@ -1,5 +1,6 @@ /* * Copyright 2010 Jacek Caban for CodeWeavers + * Copyright 2010 Thomas Mullaly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -97,6 +98,20 @@ static HRESULT WINAPI Uri_GetPropertyDWORD(IUri *iface, Uri_PROPERTY uriProp, DW { Uri *This = URI_THIS(iface); FIXME("(%p)->(%d %p %x)\n", This, uriProp, pcchProperty, dwFlags); + + if(!pcchProperty) + return E_INVALIDARG; + + /* Microsoft's implementation for the ZONE property of a URI seems to be lacking... + * From what I can tell, instead of checking which URLZONE the URI belongs to it + * simply assigns URLZONE_INVALID and returns E_NOTIMPL. This also applies to the GetZone + * function. + */ + if(uriProp == Uri_PROPERTY_ZONE) { + *pcchProperty = URLZONE_INVALID; + return E_NOTIMPL; + } + return E_NOTIMPL; } @@ -111,6 +126,10 @@ static HRESULT WINAPI Uri_GetAbsoluteUri(IUri *iface, BSTR *pstrAbsoluteUri) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrAbsoluteUri); + + if(!pstrAbsoluteUri) + return E_POINTER; + return E_NOTIMPL; } @@ -118,6 +137,10 @@ static HRESULT WINAPI Uri_GetAuthority(IUri *iface, BSTR *pstrAuthority) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrAuthority); + + if(!pstrAuthority) + return E_POINTER; + return E_NOTIMPL; } @@ -125,6 +148,10 @@ static HRESULT WINAPI Uri_GetDisplayUri(IUri *iface, BSTR *pstrDisplayUri) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrDisplayUri); + + if(!pstrDisplayUri) + return E_POINTER; + return E_NOTIMPL; } @@ -132,6 +159,10 @@ static HRESULT WINAPI Uri_GetDomain(IUri *iface, BSTR *pstrDomain) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrDomain); + + if(!pstrDomain) + return E_POINTER; + return E_NOTIMPL; } @@ -139,6 +170,10 @@ static HRESULT WINAPI Uri_GetExtension(IUri *iface, BSTR *pstrExtension) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrExtension); + + if(!pstrExtension) + return E_POINTER; + return E_NOTIMPL; } @@ -146,6 +181,10 @@ static HRESULT WINAPI Uri_GetFragment(IUri *iface, BSTR *pstrFragment) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrFragment); + + if(!pstrFragment) + return E_POINTER; + return E_NOTIMPL; } @@ -160,6 +199,10 @@ static HRESULT WINAPI Uri_GetPassword(IUri *iface, BSTR *pstrPassword) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrPassword); + + if(!pstrPassword) + return E_POINTER; + return E_NOTIMPL; } @@ -167,6 +210,10 @@ static HRESULT WINAPI Uri_GetPath(IUri *iface, BSTR *pstrPath) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrPath); + + if(!pstrPath) + return E_POINTER; + return E_NOTIMPL; } @@ -174,6 +221,10 @@ static HRESULT WINAPI Uri_GetPathAndQuery(IUri *iface, BSTR *pstrPathAndQuery) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrPathAndQuery); + + if(!pstrPathAndQuery) + return E_POINTER; + return E_NOTIMPL; } @@ -181,6 +232,10 @@ static HRESULT WINAPI Uri_GetQuery(IUri *iface, BSTR *pstrQuery) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrQuery); + + if(!pstrQuery) + return E_POINTER; + return E_NOTIMPL; } @@ -188,6 +243,10 @@ static HRESULT WINAPI Uri_GetRawUri(IUri *iface, BSTR *pstrRawUri) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrRawUri); + + if(!pstrRawUri) + return E_POINTER; + return E_NOTIMPL; } @@ -195,6 +254,10 @@ static HRESULT WINAPI Uri_GetSchemeName(IUri *iface, BSTR *pstrSchemeName) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrSchemeName); + + if(!pstrSchemeName) + return E_POINTER; + return E_NOTIMPL; } @@ -202,6 +265,10 @@ static HRESULT WINAPI Uri_GetUserInfo(IUri *iface, BSTR *pstrUserInfo) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrUserInfo); + + if(!pstrUserInfo) + return E_POINTER; + return E_NOTIMPL; } @@ -209,6 +276,10 @@ static HRESULT WINAPI Uri_GetUserName(IUri *iface, BSTR *pstrUserName) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pstrUserName); + + if(!pstrUserName) + return E_POINTER; + return E_NOTIMPL; } @@ -216,6 +287,10 @@ static HRESULT WINAPI Uri_GetHostType(IUri *iface, DWORD *pdwHostType) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwHostType); + + if(!pdwHostType) + return E_INVALIDARG; + return E_NOTIMPL; } @@ -223,6 +298,10 @@ static HRESULT WINAPI Uri_GetPort(IUri *iface, DWORD *pdwPort) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwPort); + + if(!pdwPort) + return E_INVALIDARG; + return E_NOTIMPL; } @@ -230,6 +309,10 @@ static HRESULT WINAPI Uri_GetScheme(IUri *iface, DWORD *pdwScheme) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwScheme); + + if(!pdwScheme) + return E_INVALIDARG; + return E_NOTIMPL; } @@ -237,6 +320,14 @@ static HRESULT WINAPI Uri_GetZone(IUri *iface, DWORD *pdwZone) { Uri *This = URI_THIS(iface); FIXME("(%p)->(%p)\n", This, pdwZone); + + if(!pdwZone) + return E_INVALIDARG; + + /* Microsoft doesn't seem to have this implemented yet... See + * the comment in Uri_GetPropertyDWORD for more about this. + */ + *pdwZone = URLZONE_INVALID; return E_NOTIMPL; } @@ -296,6 +387,14 @@ HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IU TRACE("(%s %x %x %p)\n", debugstr_w(pwzURI), dwFlags, (DWORD)dwReserved, ppURI); + if(!ppURI) + return E_INVALIDARG; + + if(!pwzURI) { + *ppURI = NULL; + return E_INVALIDARG; + } + ret = heap_alloc(sizeof(Uri)); if(!ret) return E_OUTOFMEMORY; diff --git a/dll/win32/user32/include/user32p.h b/dll/win32/user32/include/user32p.h index 31f38a1a7db..1ab637eeea0 100644 --- a/dll/win32/user32/include/user32p.h +++ b/dll/win32/user32/include/user32p.h @@ -33,9 +33,6 @@ #define NtUserMsqClearWakeMask() \ NtUserCallNoParam(NOPARAM_ROUTINE_MSQCLEARWAKEMASK) -#define NtUserAnyPopup() \ - (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ANYPOPUP) - #define NtUserValidateRgn(hWnd, hRgn) \ (BOOL)NtUserCallTwoParam((DWORD_PTR)hWnd, (DWORD_PTR)hRgn, TWOPARAM_ROUTINE_VALIDATERGN) diff --git a/dll/win32/user32/misc/misc.c b/dll/win32/user32/misc/misc.c index 4d786c51e52..32438366a5e 100644 --- a/dll/win32/user32/misc/misc.c +++ b/dll/win32/user32/misc/misc.c @@ -45,13 +45,6 @@ PrivateCsrssManualGuiCheck(LONG Check) NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK); } -VOID -WINAPI -PrivateCsrssInitialized(VOID) -{ - NtUserCallNoParam(NOPARAM_ROUTINE_CSRSS_INITIALIZED); -} - /* * @implemented diff --git a/dll/win32/user32/user32.pspec b/dll/win32/user32/user32.pspec index 45eb26b2b64..d58fb951d1b 100644 --- a/dll/win32/user32/user32.pspec +++ b/dll/win32/user32/user32.pspec @@ -750,7 +750,6 @@ ; ROS specific exports @ stdcall PrivateCsrssManualGuiCheck(long) -@ stdcall PrivateCsrssInitialized() ; Functions exported by Win Vista @ stdcall SetProcessDPIAware() diff --git a/dll/win32/user32/windows/class.c b/dll/win32/user32/windows/class.c index f546aa45952..1c66fd7606f 100644 --- a/dll/win32/user32/windows/class.c +++ b/dll/win32/user32/windows/class.c @@ -423,22 +423,15 @@ GetClassLongA(HWND hWnd, int nIndex) } else { - /* This is a race condition! Call win32k to make sure we're getting - the correct result */ - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ - WARN("Invalid class for hwnd 0x%p!\n", hWnd); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ + Ret = 0; } _SEH2_END; - if (Wnd == NULL) - Ret = NtUserGetClassLong(hWnd, nIndex, TRUE); - return Ret; } @@ -534,22 +527,14 @@ GetClassLongW ( HWND hWnd, int nIndex ) } else { - /* This is a race condition! Call win32k to make sure we're getting - the correct result */ - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ - WARN("Invalid class for hwnd 0x%p!\n", hWnd); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Wnd = NULL; /* Make sure we call NtUserGetClassLong */ } _SEH2_END; - if (Wnd == NULL) - Ret = NtUserGetClassLong(hWnd, nIndex, FALSE); - return Ret; } @@ -617,18 +602,28 @@ GetClassNameW( WORD WINAPI GetClassWord( - HWND hWnd, - int nIndex) -/* - * NOTE: Obsoleted in 32-bit windows - */ + HWND hwnd, + int offset) { - TRACE("%p %x\n", hWnd, nIndex); + PWND Wnd; + PCLS class; + WORD retvalue = 0; - if ((nIndex < 0) && (nIndex != GCW_ATOM)) + if (offset < 0) return GetClassLongA( hwnd, offset ); + + Wnd = ValidateHwnd(hwnd); + if (!Wnd) return 0; - return (WORD) NtUserGetClassLong ( hWnd, nIndex, TRUE ); + class = DesktopPtrToUser(Wnd->pcls); + if (class == NULL) return 0; + + if (offset <= class->cbclsExtra - sizeof(WORD)) + memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) ); + else + SetLastError( ERROR_INVALID_INDEX ); + + return retvalue; } diff --git a/dll/win32/user32/windows/menu.c b/dll/win32/user32/windows/menu.c index d5723bb3271..eed233f4947 100644 --- a/dll/win32/user32/windows/menu.c +++ b/dll/win32/user32/windows/menu.c @@ -1605,25 +1605,25 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl if( flags & TPM_BOTTOMALIGN ) y -= height; if( flags & TPM_VCENTERALIGN ) y -= height / 2; - if( x + width > info.rcWork.right) + if( x + width > info.rcMonitor.right) { if( xanchor && x >= width - xanchor ) x -= width - xanchor; - if( x + width > info.rcWork.right) - x = info.rcWork.right - width; + if( x + width > info.rcMonitor.right) + x = info.rcMonitor.right - width; } - if( x < info.rcWork.left ) x = info.rcWork.left; + if( x < info.rcMonitor.left ) x = info.rcMonitor.left; - if( y + height > info.rcWork.bottom) + if( y + height > info.rcMonitor.bottom) { if( yanchor && y >= height + yanchor ) y -= height + yanchor; - if( y + height > info.rcWork.bottom) - y = info.rcWork.bottom - height; + if( y + height > info.rcMonitor.bottom) + y = info.rcMonitor.bottom - height; } - if( y < info.rcWork.top ) y = info.rcWork.top; + if( y < info.rcMonitor.top ) y = info.rcMonitor.top; /* NOTE: In Windows, top menu popup is not owned. */ MenuInfo.Wnd = CreateWindowExW( 0, POPUPMENU_CLASS_ATOMW, NULL, diff --git a/dll/win32/user32/windows/message.c b/dll/win32/user32/windows/message.c index 5631469c03c..6c849042b7a 100644 --- a/dll/win32/user32/windows/message.c +++ b/dll/win32/user32/windows/message.c @@ -60,6 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32); * content). When a ACK message is generated, the list of pair is searched for a * matching pair, so that the client memory handle can be returned. */ + typedef struct tagDDEPAIR { HGLOBAL ClientMem; @@ -2214,11 +2215,16 @@ SendMessageCallbackA( SENDASYNCPROC lpCallBack, ULONG_PTR dwData) { + CALL_BACK_INFO CallBackInfo; + + CallBackInfo.CallBack = lpCallBack; + CallBackInfo.Context = dwData; + return NtUserMessageCall(hWnd, Msg, wParam, lParam, - (ULONG_PTR)&lpCallBack, + (ULONG_PTR)&CallBackInfo, FNID_SENDMESSAGECALLBACK, TRUE); } @@ -2236,11 +2242,17 @@ SendMessageCallbackW( SENDASYNCPROC lpCallBack, ULONG_PTR dwData) { + + CALL_BACK_INFO CallBackInfo; + + CallBackInfo.CallBack = lpCallBack; + CallBackInfo.Context = dwData; + return NtUserMessageCall(hWnd, Msg, wParam, lParam, - (ULONG_PTR)&lpCallBack, + (ULONG_PTR)&CallBackInfo, FNID_SENDMESSAGECALLBACK, FALSE); } diff --git a/dll/win32/user32/windows/window.c b/dll/win32/user32/windows/window.c index 2427cd76ee0..04533ff0aa1 100644 --- a/dll/win32/user32/windows/window.c +++ b/dll/win32/user32/windows/window.c @@ -29,9 +29,10 @@ User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength) PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs; TRACE("User32CallSendAsyncProcKernel()\n"); + CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments; - if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)) + if (ArgumentLength != sizeof(SENDASYNCPROC_CALLBACK_ARGUMENTS)) { return(STATUS_INFO_LENGTH_MISMATCH); } @@ -1029,16 +1030,16 @@ GetParent(HWND hWnd) _SEH2_TRY { WndParent = NULL; - if (Wnd->style & WS_CHILD) - { - if (Wnd->spwndParent != NULL) - WndParent = DesktopPtrToUser(Wnd->spwndParent); - } - else if (Wnd->style & WS_POPUP) + if (Wnd->style & WS_POPUP) { if (Wnd->spwndOwner != NULL) WndParent = DesktopPtrToUser(Wnd->spwndOwner); } + else if (Wnd->style & WS_CHILD) + { + if (Wnd->spwndParent != NULL) + WndParent = DesktopPtrToUser(Wnd->spwndParent); + } if (WndParent != NULL) Ret = UserHMGetHandle(WndParent); @@ -1463,7 +1464,7 @@ BOOL WINAPI IsChild(HWND hWndParent, HWND hWnd) { - PWND WndParent, Wnd; + PWND WndParent, DesktopWnd, Wnd; BOOL Ret = FALSE; WndParent = ValidateHwnd(hWndParent); @@ -1473,6 +1474,10 @@ IsChild(HWND hWndParent, if (!Wnd) return FALSE; + DesktopWnd = GetThreadDesktopWnd(); + if (!DesktopWnd) + return FALSE; + _SEH2_TRY { while (Wnd != NULL) @@ -1480,6 +1485,10 @@ IsChild(HWND hWndParent, if (Wnd->spwndParent != NULL) { Wnd = DesktopPtrToUser(Wnd->spwndParent); + + if(Wnd == DesktopWnd) + Wnd = NULL; + if (Wnd == WndParent) { Ret = TRUE; @@ -2061,7 +2070,18 @@ ScrollWindowEx(HWND hWnd, BOOL WINAPI AnyPopup(VOID) { - return NtUserAnyPopup(); + int i; + BOOL retvalue; + HWND *list = WIN_ListChildren( GetDesktopWindow() ); + + if (!list) return FALSE; + for (i = 0; list[i]; i++) + { + if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break; + } + retvalue = (list[i] != 0); + HeapFree( GetProcessHeap(), 0, list ); + return retvalue; } /* diff --git a/dll/win32/userenv/lang/es-ES.rc b/dll/win32/userenv/lang/es-ES.rc index dcfd07f92d8..8d87d2859ad 100644 --- a/dll/win32/userenv/lang/es-ES.rc +++ b/dll/win32/userenv/lang/es-ES.rc @@ -27,7 +27,7 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL STRINGTABLE BEGIN IDS_PROFILEPATH "%SystemDrive%\\Documents and Settings" - IDS_APPDATA "Application Data" + IDS_APPDATA "Datos de programa" IDS_DESKTOP "Escritorio" IDS_FAVORITES "Favoritos" IDS_STARTMENU "Menu de Inicio" @@ -39,8 +39,8 @@ BEGIN IDS_MYMUSIC "Mis Documentos\\Mi música" IDS_MYVIDEOS "Mis Documentos\\Mis videos" IDS_TEMPLATES "Plantillas" - IDS_RECENT "Documentos recientes" - IDS_SENDTO "Enviar a" + IDS_RECENT "Reciente" + IDS_SENDTO "SendTo" IDS_PRINTHOOD "Impresoras" IDS_NETHOOD "Entorno de red" IDS_LOCALSETTINGS "Configuración local" diff --git a/dll/win32/userenv/lang/it-IT.rc b/dll/win32/userenv/lang/it-IT.rc index fa6106f922e..dbbbcfa17f9 100644 --- a/dll/win32/userenv/lang/it-IT.rc +++ b/dll/win32/userenv/lang/it-IT.rc @@ -27,8 +27,8 @@ BEGIN IDS_MYMUSIC "Documenti\\Musica" IDS_MYVIDEOS "Documenti\\Video" IDS_TEMPLATES "Modelli" - IDS_RECENT "Dati recenti" - IDS_SENDTO "Invia a" + IDS_RECENT "Recent" + IDS_SENDTO "SendTo" IDS_PRINTHOOD "Stampanti" IDS_NETHOOD "Risorse di rete" IDS_LOCALSETTINGS "Impostazioni locali" diff --git a/dll/win32/winemp3.acm/winemp3.acm.rbuild b/dll/win32/winemp3.acm/winemp3.acm.rbuild index fec518725e0..be4a53bc8eb 100644 --- a/dll/win32/winemp3.acm/winemp3.acm.rbuild +++ b/dll/win32/winemp3.acm/winemp3.acm.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/dll/win32/wininet/ftp.c b/dll/win32/wininet/ftp.c index 1f031996811..80cc6f0e60a 100644 --- a/dll/win32/wininet/ftp.c +++ b/dll/win32/wininet/ftp.c @@ -1176,7 +1176,7 @@ static DWORD FTPFILE_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read) @@ -2395,7 +2395,7 @@ static DWORD FTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *bu return ERROR_SUCCESS; } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static const object_vtbl_t FTPSESSIONVtbl = { @@ -3476,7 +3476,7 @@ static DWORD FTPFINDNEXT_QueryOption(object_header_t *hdr, DWORD option, void *b return ERROR_SUCCESS; } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD FTPFINDNEXT_FindNextFileW(object_header_t *hdr, void *data) diff --git a/dll/win32/wininet/http.c b/dll/win32/wininet/http.c index 57b73729a10..d14a52281e7 100644 --- a/dll/win32/wininet/http.c +++ b/dll/win32/wininet/http.c @@ -1756,7 +1756,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, DWORD size) @@ -3464,6 +3464,10 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, * for all the data */ HTTP_DrainContent(lpwhr); lpwhr->dwContentRead = 0; + if(redirected) { + lpwhr->dwContentLength = ~0u; + lpwhr->dwBytesToWrite = 0; + } if (TRACE_ON(wininet)) { @@ -3670,7 +3674,7 @@ lend: HTTP_ReceiveRequestData(lpwhr, TRUE); else { - iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; + iar.dwResult = 0; iar.dwError = res; INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, @@ -4164,7 +4168,7 @@ static DWORD HTTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *b return ERROR_SUCCESS; } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static DWORD HTTPSESSION_SetOption(object_header_t *hdr, DWORD option, void *buffer, DWORD size) @@ -4261,11 +4265,8 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if(hIC->lpszProxyBypass) FIXME("Proxy bypass is ignored.\n"); } - if (lpszServerName && lpszServerName[0]) - { - lpwhs->lpszServerName = heap_strdupW(lpszServerName); - lpwhs->lpszHostName = heap_strdupW(lpszServerName); - } + lpwhs->lpszServerName = heap_strdupW(lpszServerName); + lpwhs->lpszHostName = heap_strdupW(lpszServerName); if (lpszUserName && lpszUserName[0]) lpwhs->lpszUserName = heap_strdupW(lpszUserName); if (lpszPassword && lpszPassword[0]) @@ -4362,6 +4363,10 @@ static DWORD HTTP_OpenConnection(http_request_t *lpwhr) if(res != ERROR_SUCCESS) goto lend; + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_CONNECTED_TO_SERVER, + szaddr, strlen(szaddr)+1); + if (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE) { /* Note: we differ from Microsoft's WinINet here. they seem to have @@ -4370,20 +4375,31 @@ static DWORD HTTP_OpenConnection(http_request_t *lpwhr) * behaviour to be more correct and to not cause any incompatibilities * because using a secure connection through a proxy server is a rare * case that would be hard for anyone to depend on */ - if (hIC->lpszProxy && (res = HTTP_SecureProxyConnect(lpwhr)) != ERROR_SUCCESS) + if (hIC->lpszProxy && (res = HTTP_SecureProxyConnect(lpwhr)) != ERROR_SUCCESS) { + HTTPREQ_CloseConnection(&lpwhr->hdr); goto lend; + } res = NETCON_secure_connect(&lpwhr->netConnection, lpwhs->lpszHostName); if(res != ERROR_SUCCESS) { WARN("Couldn't connect securely to host\n"); + + if((lpwhr->hdr.ErrorMask&INTERNET_ERROR_MASK_COMBINED_SEC_CERT) && ( + res == ERROR_INTERNET_SEC_CERT_DATE_INVALID + || res == ERROR_INTERNET_INVALID_CA + || res == ERROR_INTERNET_SEC_CERT_NO_REV + || res == ERROR_INTERNET_SEC_CERT_REV_FAILED + || res == ERROR_INTERNET_SEC_CERT_REVOKED + || res == ERROR_INTERNET_SEC_INVALID_CERT + || res == ERROR_INTERNET_SEC_CERT_CN_INVALID)) + res = ERROR_INTERNET_SEC_CERT_ERRORS; + + HTTPREQ_CloseConnection(&lpwhr->hdr); goto lend; } } - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_CONNECTED_TO_SERVER, - szaddr, strlen(szaddr)+1); lend: lpwhr->read_pos = lpwhr->read_size = 0; diff --git a/dll/win32/wininet/internet.c b/dll/win32/wininet/internet.c index 6fc8a212c89..001736001a4 100644 --- a/dll/win32/wininet/internet.c +++ b/dll/win32/wininet/internet.c @@ -812,7 +812,7 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } - return INET_QueryOption(option, buffer, size, unicode); + return INET_QueryOption(hdr, option, buffer, size, unicode); } static const object_vtbl_t APPINFOVtbl = { @@ -1447,7 +1447,7 @@ BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, lpUrlComponents->nScheme = UCW.nScheme; lpUrlComponents->nPort = UCW.nPort; - TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", lpszUrl, + TRACE("%s: scheme(%s) host(%s) path(%s) extra(%s)\n", debugstr_a(lpszUrl), debugstr_an(lpUrlComponents->lpszScheme, lpUrlComponents->dwSchemeLength), debugstr_an(lpUrlComponents->lpszHostName, lpUrlComponents->dwHostNameLength), debugstr_an(lpUrlComponents->lpszUrlPath, lpUrlComponents->dwUrlPathLength), @@ -1860,7 +1860,7 @@ BOOL WINAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer, DWORD dwURLFlags = URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE; TRACE("(%s, %p, %p, 0x%08x) bufferlength: %d\n", debugstr_a(lpszUrl), lpszBuffer, - lpdwBufferLength, lpdwBufferLength ? *lpdwBufferLength : -1, dwFlags); + lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1); if(dwFlags & ICU_DECODE) { @@ -2194,7 +2194,7 @@ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, return res == ERROR_SUCCESS; } -DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) +DWORD INET_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { static BOOL warn = TRUE; @@ -2357,6 +2357,25 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) return ERROR_INTERNET_INCORRECT_HANDLE_TYPE; case INTERNET_OPTION_POLICY: return ERROR_INVALID_PARAMETER; + case INTERNET_OPTION_CONTEXT_VALUE: + { + if (!hdr) + return ERROR_INTERNET_INCORRECT_HANDLE_TYPE; + if (!size) + return ERROR_INVALID_PARAMETER; + + if (*size < sizeof(DWORD_PTR)) + { + *size = sizeof(DWORD_PTR); + return ERROR_INSUFFICIENT_BUFFER; + } + if (!buffer) + return ERROR_INVALID_PARAMETER; + + *(DWORD_PTR *)buffer = hdr->dwContext; + *size = sizeof(DWORD_PTR); + return ERROR_SUCCESS; + } } FIXME("Stub for %d\n", option); @@ -2388,7 +2407,7 @@ BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, WININET_Release(hdr); } }else { - res = INET_QueryOption(dwOption, lpBuffer, lpdwBufferLength, TRUE); + res = INET_QueryOption(NULL, dwOption, lpBuffer, lpdwBufferLength, TRUE); } if(res != ERROR_SUCCESS) @@ -2421,7 +2440,7 @@ BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, WININET_Release(hdr); } }else { - res = INET_QueryOption(dwOption, lpBuffer, lpdwBufferLength, FALSE); + res = INET_QueryOption(NULL, dwOption, lpBuffer, lpdwBufferLength, FALSE); } if(res != ERROR_SUCCESS) @@ -2484,8 +2503,19 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, break; case INTERNET_OPTION_ERROR_MASK: { - ULONG flags = *(ULONG *)lpBuffer; - FIXME("Option INTERNET_OPTION_ERROR_MASK(%d): STUB\n", flags); + if(!lpwhh) { + SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); + return FALSE; + } else if(*(ULONG*)lpBuffer & (~(INTERNET_ERROR_MASK_INSERT_CDROM| + INTERNET_ERROR_MASK_COMBINED_SEC_CERT| + INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY))) { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } else if(dwBufferLength != sizeof(ULONG)) { + SetLastError(ERROR_INTERNET_BAD_OPTION_LENGTH); + ret = FALSE; + } else + lpwhh->ErrorMask = *(ULONG*)lpBuffer; } break; case INTERNET_OPTION_CODEPAGE: @@ -2550,8 +2580,21 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, break; } case INTERNET_OPTION_CONTEXT_VALUE: - FIXME("Option INTERNET_OPTION_CONTEXT_VALUE; STUB\n"); - break; + { + if (!lpwhh) + { + SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); + return FALSE; + } + if (!lpBuffer || dwBufferLength != sizeof(DWORD_PTR)) + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + else + lpwhh->dwContext = *(DWORD_PTR *)lpBuffer; + break; + } case INTERNET_OPTION_SECURITY_FLAGS: FIXME("Option INTERNET_OPTION_SECURITY_FLAGS; STUB\n"); break; diff --git a/dll/win32/wininet/internet.h b/dll/win32/wininet/internet.h index 8fcc0cf3565..a531ccd752f 100644 --- a/dll/win32/wininet/internet.h +++ b/dll/win32/wininet/internet.h @@ -160,6 +160,7 @@ struct _object_header_t DWORD dwFlags; DWORD_PTR dwContext; DWORD dwError; + ULONG ErrorMask; DWORD dwInternalFlags; LONG refs; INTERNET_STATUS_CALLBACK lpfnStatusCB; @@ -392,7 +393,7 @@ object_header_t *WININET_AddRef( object_header_t *info ); BOOL WININET_Release( object_header_t *info ); BOOL WININET_FreeHandle( HINTERNET hinternet ); -DWORD INET_QueryOption(DWORD,void*,DWORD*,BOOL); +DWORD INET_QueryOption( object_header_t *, DWORD, void *, DWORD *, BOOL ); time_t ConvertTimeString(LPCWSTR asctime); diff --git a/dll/win32/wininet/netconnection.c b/dll/win32/wininet/netconnection.c index c2560b5da37..5aa647a7a49 100644 --- a/dll/win32/wininet/netconnection.c +++ b/dll/win32/wininet/netconnection.c @@ -134,6 +134,7 @@ MAKE_FUNCPTR(SSL_shutdown); MAKE_FUNCPTR(SSL_write); MAKE_FUNCPTR(SSL_read); MAKE_FUNCPTR(SSL_pending); +MAKE_FUNCPTR(SSL_get_error); MAKE_FUNCPTR(SSL_get_ex_new_index); MAKE_FUNCPTR(SSL_get_ex_data); MAKE_FUNCPTR(SSL_set_ex_data); @@ -330,7 +331,9 @@ static int netconn_secure_verify(int preverify_ok, X509_STORE_CTX *ctx) CertFreeCertificateContext(endCert); CertCloseStore(store, 0); } - } + } else + pSSL_set_ex_data(ssl, error_idx, (void *)ERROR_INTERNET_SEC_CERT_ERRORS); + return ret; } @@ -392,6 +395,7 @@ DWORD NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) DYNSSL(SSL_write); DYNSSL(SSL_read); DYNSSL(SSL_pending); + DYNSSL(SSL_get_error); DYNSSL(SSL_get_ex_new_index); DYNSSL(SSL_get_ex_data); DYNSSL(SSL_set_ex_data); @@ -772,6 +776,12 @@ DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int { #ifdef SONAME_LIBSSL *recvd = pSSL_read(connection->ssl_s, buf, len); + + /* Check if EOF was received */ + if(!*recvd && (pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_ZERO_RETURN + || pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_SYSCALL)) + return ERROR_SUCCESS; + return *recvd > 0 ? ERROR_SUCCESS : ERROR_INTERNET_CONNECTION_ABORTED; #else return ERROR_NOT_SUPPORTED; diff --git a/dll/win32/wininet/urlcache.c b/dll/win32/wininet/urlcache.c index 6a39c691475..c617a93299f 100644 --- a/dll/win32/wininet/urlcache.c +++ b/dll/win32/wininet/urlcache.c @@ -2435,7 +2435,6 @@ static BOOL CommitUrlCacheEntryInternal( DWORD dwFileSizeLow = 0; DWORD dwFileSizeHigh = 0; BYTE cDirectory = 0; - int len; char achFile[MAX_PATH]; LPSTR lpszUrlNameA = NULL; LPSTR lpszFileExtensionA = NULL; @@ -2556,7 +2555,6 @@ static BOOL CommitUrlCacheEntryInternal( dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszUrlNameA) + 1); if (lpszLocalFileName) { - len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL); dwOffsetLocalFileName = dwBytesNeeded; dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(pchLocalFileName) + 1); } diff --git a/dll/win32/wininet/utility.c b/dll/win32/wininet/utility.c index 66fbecdd653..0639f40385e 100644 --- a/dll/win32/wininet/utility.c +++ b/dll/win32/wininet/utility.c @@ -307,6 +307,7 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, case INTERNET_STATUS_CONNECTING_TO_SERVER: case INTERNET_STATUS_CONNECTED_TO_SERVER: lpvNewInfo = heap_strdupAtoW(lpvStatusInfo); + dwStatusInfoLength *= sizeof(WCHAR); break; case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: @@ -325,6 +326,7 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: lpvNewInfo = heap_strdupWtoA(lpvStatusInfo); + dwStatusInfoLength /= sizeof(WCHAR); break; } } diff --git a/dll/win32/wininet/wininet.rbuild b/dll/win32/wininet/wininet.rbuild index 45b87b18665..ac2c43f7945 100644 --- a/dll/win32/wininet/wininet.rbuild +++ b/dll/win32/wininet/wininet.rbuild @@ -6,6 +6,7 @@ . include/reactos/wine + . @@ -22,6 +23,7 @@ secur32 crypt32 ws2_32 + zlib pseh cookie.c dialogs.c diff --git a/dll/win32/wininet/wininet_Si.rc b/dll/win32/wininet/wininet_Si.rc index b5bf2914328..488104ec9dc 100644 --- a/dll/win32/wininet/wininet_Si.rc +++ b/dll/win32/wininet/wininet_Si.rc @@ -27,11 +27,11 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Vnos omreĹľnega gesla" FONT 8, "MS Shell Dlg" { - LTEXT "Vnesite uporabniško ime in geslo:", -1, 40, 6, 150, 15 - LTEXT "Proksi", -1, 40, 26, 50, 10 - LTEXT "Kraljestvo", -1, 40, 46, 50, 10 - LTEXT "Uporabniško ime", -1, 40, 66, 50, 10 - LTEXT "Geslo", -1, 40, 86, 50, 10 + LTEXT "Vnesite uporabniško ime in geslo:", -1, 20, 6, 150, 15 + LTEXT "Proksi", -1, 20, 26, 50, 10 + LTEXT "PodroÄŤje", -1, 20, 46, 50, 10 + LTEXT "Uporabniško ime", -1, 20, 66, 55, 10 + LTEXT "Geslo", -1, 20, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP @@ -42,6 +42,26 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "PrekliÄŤi", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } +IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Authentication Required" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Vnesite uporabniško ime in geslo:", -1, 20, 6, 150, 15 + LTEXT "Server", -1, 20, 26, 50, 10 + LTEXT "PodroÄŤje", -1, 20, 46, 50, 10 + LTEXT "Uporabniško ime", -1, 20, 66, 55, 10 + LTEXT "Geslo", -1, 20, 86, 50, 10 + LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "&Shrani geslo (nezaščiteno)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "V redu", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "PrekliÄŤi", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} + STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN povezava" diff --git a/dll/win32/wintrust/wintrust.rbuild b/dll/win32/wintrust/wintrust.rbuild index 910d2278f8e..bcb1c2b8304 100644 --- a/dll/win32/wintrust/wintrust.rbuild +++ b/dll/win32/wintrust/wintrust.rbuild @@ -1,4 +1,4 @@ - + . diff --git a/dll/win32/ws2_32/misc/ns.c b/dll/win32/ws2_32/misc/ns.c index fee4f032868..04e5b4bc5e2 100644 --- a/dll/win32/ws2_32/misc/ns.c +++ b/dll/win32/ws2_32/misc/ns.c @@ -32,10 +32,44 @@ WSAAddressToStringA(IN LPSOCKADDR lpsaAddress, OUT LPSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength) { - UNIMPLEMENTED + DWORD size; + CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ + CHAR *p; - WSASetLastError(WSASYSCALLFAILURE); - return SOCKET_ERROR; + if (!lpsaAddress) return SOCKET_ERROR; + if (!lpszAddressString || !lpdwAddressStringLength) return SOCKET_ERROR; + + switch(lpsaAddress->sa_family) + { + case AF_INET: + if (dwAddressLength < sizeof(SOCKADDR_IN)) return SOCKET_ERROR; + sprintf( buffer, "%u.%u.%u.%u:%u", + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 24 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 16 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 8 & 0xff), + (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) & 0xff), + ntohs( ((SOCKADDR_IN *)lpsaAddress)->sin_port ) ); + + p = strchr( buffer, ':' ); + if (!((SOCKADDR_IN *)lpsaAddress)->sin_port) *p = 0; + break; + default: + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + + size = strlen( buffer ) + 1; + + if (*lpdwAddressStringLength < size) + { + *lpdwAddressStringLength = size; + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + *lpdwAddressStringLength = size; + strcpy( lpszAddressString, buffer ); + return 0; } @@ -50,10 +84,28 @@ WSAAddressToStringW(IN LPSOCKADDR lpsaAddress, OUT LPWSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength) { - UNIMPLEMENTED + INT ret; + DWORD size; + WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */ + CHAR bufAddr[54]; - WSASetLastError(WSASYSCALLFAILURE); - return SOCKET_ERROR; + size = *lpdwAddressStringLength; + ret = WSAAddressToStringA(lpsaAddress, dwAddressLength, NULL, bufAddr, &size); + + if (ret) return ret; + + MultiByteToWideChar( CP_ACP, 0, bufAddr, size, buffer, sizeof( buffer )/sizeof(WCHAR)); + + if (*lpdwAddressStringLength < size) + { + *lpdwAddressStringLength = size; + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + *lpdwAddressStringLength = size; + lstrcpyW( lpszAddressString, buffer ); + return 0; } diff --git a/dll/win32/ws2_32/misc/sndrcv.c b/dll/win32/ws2_32/misc/sndrcv.c index f1b68feb158..8fb4186933e 100644 --- a/dll/win32/ws2_32/misc/sndrcv.c +++ b/dll/win32/ws2_32/misc/sndrcv.c @@ -410,6 +410,8 @@ WSASendTo(IN SOCKET s, if (Code == SOCKET_ERROR) WSASetLastError(Errno); + else + WSASetLastError(0); return Code; } diff --git a/drivers/base/bootvid/i386/bootvid.c b/drivers/base/bootvid/i386/bootvid.c index 3d0ae503167..08d0dc10b8e 100644 --- a/drivers/base/bootvid/i386/bootvid.c +++ b/drivers/base/bootvid/i386/bootvid.c @@ -155,7 +155,7 @@ VgaInterpretCmdStream(IN PUSHORT CmdStream) if (!ShortValue) continue; /* Loop the cmd array */ - for (; Count; Count--, CmdStream++, Value++) + for (; Count; Count--, CmdStream++) { /* Get the byte we're writing */ ShortValue += (*CmdStream) << 8; diff --git a/drivers/base/bootvid/i386/vga.c b/drivers/base/bootvid/i386/vga.c index eeb06fe8df5..1c80994c0e7 100644 --- a/drivers/base/bootvid/i386/vga.c +++ b/drivers/base/bootvid/i386/vga.c @@ -402,33 +402,20 @@ BitBlt(IN ULONG Left, IN ULONG BitsPerPixel, IN ULONG Delta) { - ULONG LeftAnd, LeftShifted, LeftPlusOne, LeftPos; - ULONG lMask, rMask; - UCHAR NotlMask; - ULONG Distance; - ULONG DistanceMinusLeftBpp; - ULONG SomeYesNoFlag, SomeYesNoFlag2; - PUCHAR PixelPosition, m; - PUCHAR i, k; - ULONG j; - ULONG x; - ULONG Plane; - UCHAR LeftArray[84]; - PUCHAR CurrentLeft; - PUCHAR l; - ULONG LoopCount; - UCHAR pMask, PlaneShift; - BOOLEAN Odd; - UCHAR Value; + ULONG sx, dx, dy; + UCHAR color; + ULONG offset = 0; + const ULONG Bottom = Top + Height; + const ULONG Right = Left + Width; /* Check if the buffer isn't 4bpp */ if (BitsPerPixel != 4) { /* FIXME: TODO */ DbgPrint("Unhandled BitBlt\n" - "%lxx%lx @ (%lx,%lx)\n" - "Bits Per Pixel %lx\n" - "Buffer: %p. Delta: %lx\n", + "%lux%lu @ (%lu|%lu)\n" + "Bits Per Pixel %lu\n" + "Buffer: %p. Delta: %lu\n", Width, Height, Left, @@ -439,181 +426,28 @@ BitBlt(IN ULONG Left, return; } - /* Get the masks and other values */ - LeftAnd = Left & 0x7; - lMask = lMaskTable[LeftAnd]; - Distance = Width + Left; - rMask = rMaskTable[(Distance - 1) & 0x7]; - Left >>= 3; - - /* Set some values */ - SomeYesNoFlag = FALSE; - SomeYesNoFlag2 = FALSE; - Distance = (Distance - 1) >> 3; - DistanceMinusLeftBpp = Distance - Left; - - /* Check if the distance is equal to the left position and add the masks */ - if (Left == Distance) lMask += rMask; - - /* Check if there's no distance offset */ - if (DistanceMinusLeftBpp) - { - /* Set the first flag on */ - SomeYesNoFlag = TRUE; - - /* Decrease offset and check if we still have one */ - if (--DistanceMinusLeftBpp) - { - /* Still have a distance offset */ - SomeYesNoFlag2 = TRUE; - } - } - - /* Calculate initial pixel position */ - PixelPosition = (PUCHAR)VgaBase + (Top * 80) + Left; - - /* Set loop buffer variable */ - i = Buffer; - - /* Switch to mode 0 */ - ReadWriteMode(0); - - /* Leave now if the height is 0 */ - if (Height <= 0) return; - - /* Set more weird values */ - CurrentLeft = &LeftArray[Left]; - NotlMask = ~(UCHAR)lMask; - LeftPlusOne = Left + 1; - LeftShifted = (lMask << 8) | 8; - j = Height; - - /* Start the height loop */ + /* 4bpp blitting */ + dy = Top; do { - /* Start the plane loop */ - Plane = 0; + sx = 0; do { - /* Clear the current value */ - *CurrentLeft = 0; - LoopCount = 0; + /* Extract color */ + color = Buffer[offset + sx]; - /* Set the buffer loop variable for this loop */ - k = i; + /* Calc destination x */ + dx = Left + (sx << 1); - /* Calculate plane shift and pixel mask */ - PlaneShift = 1 << Plane; - pMask = PixelMask[LeftAnd]; + /* Set two pixels */ + SetPixel(dx, dy, color >> 4); + SetPixel(dx + 1, dy, color & 0x0F); - /* Check if we have a width */ - if (Width > 0) - { - /* Loop it */ - l = CurrentLeft; - x = Width; - do - { - /* Check if we're odd and increase the loop count */ - Odd = LoopCount & 1 ? TRUE : FALSE; - LoopCount++; - if (Odd) - { - /* Check for the plane shift */ - if (*k & PlaneShift) - { - /* Write the pixel mask */ - *l |= pMask; - } - - /* Increase buffer position */ - k++; - } - else - { - /* Check for plane shift */ - if ((*k >> 4) & PlaneShift) - { - /* Write the pixel mask */ - *l |= pMask; - } - } - - /* Shift the pixel mask */ - pMask >>= 1; - if (!pMask) - { - /* Move to the next current left position and clear it */ - l++; - *l = 0; - - /* Set the pixel mask to 0x80 */ - pMask = 0x80; - } - } while (--x); - } - - /* Set the plane value */ - __outpw(0x3C4, (1 << (Plane + 8) | 2)); - - /* Select the bitmask register and write the mask */ - __outpw(0x3CE, (USHORT)LeftShifted); - - /* Read the current Pixel value */ - Value = READ_REGISTER_UCHAR(PixelPosition); - - /* Add our mask */ - Value = (Value & NotlMask) | *CurrentLeft; - - /* Set current left for the loop, and write new pixel value */ - LeftPos = LeftPlusOne; - WRITE_REGISTER_UCHAR(PixelPosition, Value); - - /* Set loop pixel position and check if we should loop */ - m = PixelPosition + 1; - if (SomeYesNoFlag2) - { - /* Set the bitmask to 0xFF for all 4 planes */ - __outpw(0x3CE, 0xFF08); - - /* Check if we have any distance left */ - if (DistanceMinusLeftBpp > 0) - { - /* Start looping it */ - x = DistanceMinusLeftBpp; - do - { - /* Write the value */ - WRITE_REGISTER_UCHAR(m, LeftArray[LeftPos]); - - /* Go to the next position */ - m++; - LeftPos++; - } while (--x); - } - } - - /* Check if the first flag is on */ - if (SomeYesNoFlag) - { - /* Set the mask value */ - __outpw(0x3CE, (rMask << 8) | 8); - - /* Read the current Pixel value */ - Value = READ_REGISTER_UCHAR(m); - - /* Add our mask */ - Value = (Value & ~(UCHAR)rMask) | LeftArray[LeftPos]; - - /* Set current left for the loop, and write new pixel value */ - WRITE_REGISTER_UCHAR(m, Value); - } - } while (++Plane < 4); - - /* Update pixel position, buffer and height */ - PixelPosition += 80; - i += Delta; - } while (--j); + sx++; + } while (dx < Right); + offset += Delta; + dy++; + } while (dy < Bottom); } VOID diff --git a/drivers/battery/battc/battc.rbuild b/drivers/battery/battc/battc.rbuild index c0261344994..5847dd401b0 100644 --- a/drivers/battery/battc/battc.rbuild +++ b/drivers/battery/battc/battc.rbuild @@ -5,6 +5,7 @@ hal . + battc.c battc.rc diff --git a/drivers/bus/acpi/acpica/include/platform/acwin64.h b/drivers/bus/acpi/acpica/include/platform/acwin64.h index faec855e22d..59a8adda807 100644 --- a/drivers/bus/acpi/acpica/include/platform/acwin64.h +++ b/drivers/bus/acpi/acpica/include/platform/acwin64.h @@ -118,10 +118,14 @@ /*! [Begin] no source code translation (Keep the include) */ -#include "acintel.h" +//#include "acintel.h" +// HACK +#define INT32 _ACPI_INT32 +#define UINT32 _ACPI_UINT32 + /*! [End] no source code translation !*/ -#define ACPI_MACHINE_WIDTH 64 +#define ACPI_MACHINE_WIDTH 64 #define ACPI_USE_STANDARD_HEADERS diff --git a/drivers/bus/acpi/busmgr/bus.c b/drivers/bus/acpi/busmgr/bus.c index ae04c2cb31b..9860055873a 100644 --- a/drivers/bus/acpi/busmgr/bus.c +++ b/drivers/bus/acpi/busmgr/bus.c @@ -457,6 +457,7 @@ acpi_bus_get_perf_flags ( -------------------------------------------------------------------------- */ void +NTAPI acpi_bus_generate_event_dpc(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, diff --git a/drivers/bus/acpi/compbatt/compbatt.c b/drivers/bus/acpi/compbatt/compbatt.c index a0b17f83e45..094cb4e6b6e 100644 --- a/drivers/bus/acpi/compbatt/compbatt.c +++ b/drivers/bus/acpi/compbatt/compbatt.c @@ -214,15 +214,6 @@ CompBattSetStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -NTAPI -CompBattGetBatteryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, - IN ULONG Tag) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS NTAPI CompBattQueryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, diff --git a/drivers/bus/acpi/include/acpisys.h b/drivers/bus/acpi/include/acpisys.h index adf2a0c592a..eb171f15546 100644 --- a/drivers/bus/acpi/include/acpisys.h +++ b/drivers/bus/acpi/include/acpisys.h @@ -130,6 +130,7 @@ Bus_PnP ( ); NTSTATUS +NTAPI Bus_CompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, diff --git a/drivers/bus/acpi/interface.c b/drivers/bus/acpi/interface.c index 59717056484..4e54115c0b4 100644 --- a/drivers/bus/acpi/interface.c +++ b/drivers/bus/acpi/interface.c @@ -25,13 +25,14 @@ AcpiInterfaceDereference(PVOID Context) } NTSTATUS +NTAPI AcpiInterfaceConnectVector(PDEVICE_OBJECT Context, ULONG GpeNumber, KINTERRUPT_MODE Mode, BOOLEAN Shareable, PGPE_SERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext, - PVOID *ObjectContext) + PVOID ObjectContext) { UNIMPLEMENTED @@ -39,8 +40,8 @@ AcpiInterfaceConnectVector(PDEVICE_OBJECT Context, } NTSTATUS -AcpiInterfaceDisconnectVector(PDEVICE_OBJECT Context, - PVOID ObjectContext) +NTAPI +AcpiInterfaceDisconnectVector(PVOID ObjectContext) { UNIMPLEMENTED @@ -48,6 +49,7 @@ AcpiInterfaceDisconnectVector(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceEnableEvent(PDEVICE_OBJECT Context, PVOID ObjectContext) { @@ -57,6 +59,7 @@ AcpiInterfaceEnableEvent(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceDisableEvent(PDEVICE_OBJECT Context, PVOID ObjectContext) { @@ -66,6 +69,7 @@ AcpiInterfaceDisableEvent(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceClearStatus(PDEVICE_OBJECT Context, PVOID ObjectContext) { @@ -75,6 +79,7 @@ AcpiInterfaceClearStatus(PDEVICE_OBJECT Context, } NTSTATUS +NTAPI AcpiInterfaceNotificationsRegister(PDEVICE_OBJECT Context, PDEVICE_NOTIFY_CALLBACK NotificationHandler, PVOID NotificationContext) @@ -85,6 +90,7 @@ AcpiInterfaceNotificationsRegister(PDEVICE_OBJECT Context, } VOID +NTAPI AcpiInterfaceNotificationsUnregister(PDEVICE_OBJECT Context, PDEVICE_NOTIFY_CALLBACK NotificationHandler) { diff --git a/drivers/bus/acpi/pnp.c b/drivers/bus/acpi/pnp.c index c82a3905023..9259fb9d2a5 100644 --- a/drivers/bus/acpi/pnp.c +++ b/drivers/bus/acpi/pnp.c @@ -363,6 +363,7 @@ Bus_SendIrpSynchronously ( } NTSTATUS +NTAPI Bus_CompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, diff --git a/drivers/filesystems/npfs/create.c b/drivers/filesystems/npfs/create.c index 5236e2035ee..bef462fb8d7 100644 --- a/drivers/filesystems/npfs/create.c +++ b/drivers/filesystems/npfs/create.c @@ -205,8 +205,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, ClientCcb->MaxDataLength = Fcb->OutboundQuota; ExInitializeFastMutex(&ClientCcb->DataListLock); KeInitializeEvent(&ClientCcb->ConnectEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&ClientCcb->ReadEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&ClientCcb->WriteEvent, SynchronizationEvent, FALSE); + KeInitializeEvent(&ClientCcb->ReadEvent, NotificationEvent, FALSE); + KeInitializeEvent(&ClientCcb->WriteEvent, NotificationEvent, FALSE); /* @@ -255,8 +255,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, if (ClientCcb->Data) { ExFreePool(ClientCcb->Data); - ClientCcb->Data = NULL; } + + ExFreePool(ClientCcb); KeUnlockMutex(&Fcb->CcbListLock); Irp->IoStatus.Status = STATUS_OBJECT_PATH_NOT_FOUND; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -273,6 +274,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject, else if (IsListEmpty(&Fcb->ServerCcbListHead)) { DPRINT("No server fcb found!\n"); + + if (ClientCcb->Data) + { + ExFreePool(ClientCcb->Data); + } + + ExFreePool(ClientCcb); + KeUnlockMutex(&Fcb->CcbListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -540,8 +549,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, DPRINT("CCB: %p\n", Ccb); KeInitializeEvent(&Ccb->ConnectEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&Ccb->ReadEvent, SynchronizationEvent, FALSE); - KeInitializeEvent(&Ccb->WriteEvent, SynchronizationEvent, FALSE); + KeInitializeEvent(&Ccb->ReadEvent, NotificationEvent, FALSE); + KeInitializeEvent(&Ccb->WriteEvent, NotificationEvent, FALSE); KeLockMutex(&Fcb->CcbListLock); InsertTailList(&Fcb->ServerCcbListHead, &Ccb->CcbListEntry); @@ -619,7 +628,6 @@ NpfsCleanup(PDEVICE_OBJECT DeviceObject, ExAcquireFastMutex(&OtherSide->DataListLock); ExAcquireFastMutex(&Ccb->DataListLock); } - //OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE; OtherSide->OtherSide = NULL; /* * Signaling the write event. If is possible that an other @@ -743,8 +751,11 @@ NpfsClose(PDEVICE_OBJECT DeviceObject, } /* Disconnect the pipes */ - if (Ccb->OtherSide) Ccb->OtherSide->OtherSide = NULL; - if (Ccb) Ccb->OtherSide = NULL; + if (Ccb->OtherSide) + { + Ccb->OtherSide->OtherSide = NULL; + Ccb->OtherSide = NULL; + } ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE); diff --git a/drivers/filesystems/npfs/finfo.c b/drivers/filesystems/npfs/finfo.c index 18c53414d64..fbb1d6090de 100644 --- a/drivers/filesystems/npfs/finfo.c +++ b/drivers/filesystems/npfs/finfo.c @@ -26,6 +26,13 @@ NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject, PFILE_PIPE_INFORMATION Request; DPRINT("NpfsSetPipeInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_INFORMATION)) + { + /* Buffer too small */ + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* Get the Pipe and data */ Fcb = Ccb->Fcb; Request = (PFILE_PIPE_INFORMATION)Info; @@ -63,6 +70,12 @@ NpfsSetPipeRemoteInformation(PDEVICE_OBJECT DeviceObject, PFILE_PIPE_REMOTE_INFORMATION Request; DPRINT("NpfsSetPipeRemoteInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_REMOTE_INFORMATION)) + { + /* Buffer too small */ + return STATUS_INFO_LENGTH_MISMATCH; + } + /* Get the Pipe and data */ Fcb = Ccb->Fcb; Request = (PFILE_PIPE_REMOTE_INFORMATION)Info; @@ -86,6 +99,13 @@ NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject, ULONG ConnectionSideReadMode; DPRINT("NpfsQueryPipeInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_INFORMATION)) + { + /* Buffer too small */ + *BufferLength = sizeof(FILE_PIPE_INFORMATION); + return STATUS_BUFFER_OVERFLOW; + } + /* Get the Pipe */ Fcb = Ccb->Fcb; @@ -100,7 +120,7 @@ NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject, Info->ReadMode = ConnectionSideReadMode; /* Return success */ - *BufferLength -= sizeof(FILE_PIPE_INFORMATION); + *BufferLength = sizeof(FILE_PIPE_INFORMATION); return STATUS_SUCCESS; } @@ -114,6 +134,13 @@ NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject, PNPFS_FCB Fcb; DPRINT("NpfsQueryPipeRemoteInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_REMOTE_INFORMATION)) + { + /* Buffer too small */ + *BufferLength = sizeof(FILE_PIPE_REMOTE_INFORMATION); + return STATUS_BUFFER_OVERFLOW; + } + /* Get the Pipe */ Fcb = Ccb->Fcb; @@ -125,7 +152,7 @@ NpfsQueryPipeRemoteInformation(PDEVICE_OBJECT DeviceObject, Info->CollectDataTime = Fcb->TimeOut; /* Return success */ - *BufferLength -= sizeof(FILE_PIPE_REMOTE_INFORMATION); + *BufferLength = sizeof(FILE_PIPE_REMOTE_INFORMATION); return STATUS_SUCCESS; } @@ -140,11 +167,21 @@ NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject, DPRINT("NpfsQueryLocalPipeInformation()\n"); + if (*BufferLength < sizeof(FILE_PIPE_REMOTE_INFORMATION)) + { + /* Buffer too small */ + *BufferLength = sizeof(FILE_PIPE_REMOTE_INFORMATION); + return STATUS_BUFFER_OVERFLOW; + } + + /* Get the Pipe */ Fcb = Ccb->Fcb; + /* Clear Info */ RtlZeroMemory(Info, sizeof(FILE_PIPE_LOCAL_INFORMATION)); + /* Return Info */ Info->NamedPipeType = Fcb->PipeType; Info->NamedPipeConfiguration = Fcb->PipeConfiguration; Info->MaximumInstances = Fcb->MaximumInstances; @@ -165,7 +202,7 @@ NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject, Info->WriteQuotaAvailable = Ccb->OtherSide->WriteQuotaAvailable; } - *BufferLength -= sizeof(FILE_PIPE_LOCAL_INFORMATION); + *BufferLength = sizeof(FILE_PIPE_LOCAL_INFORMATION); return STATUS_SUCCESS; } @@ -226,14 +263,12 @@ NpfsQueryInformation(PDEVICE_OBJECT DeviceObject, default: Status = STATUS_NOT_SUPPORTED; + BufferLength = 0; } Irp->IoStatus.Status = Status; - if (NT_SUCCESS(Status)) - Irp->IoStatus.Information = - IoStack->Parameters.QueryFile.Length - BufferLength; - else - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = BufferLength; + IoCompleteRequest (Irp, IO_NO_INCREMENT); return Status; diff --git a/drivers/filesystems/npfs/npfs.c b/drivers/filesystems/npfs/npfs.c index ed6d6005221..147f4107b52 100644 --- a/drivers/filesystems/npfs/npfs.c +++ b/drivers/filesystems/npfs/npfs.c @@ -70,6 +70,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, /* initialize the device object */ DeviceObject->Flags |= DO_DIRECT_IO; + DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; /* initialize the device extension */ DeviceExtension = DeviceObject->DeviceExtension; diff --git a/drivers/filesystems/npfs/rw.c b/drivers/filesystems/npfs/rw.c index 7b14449b308..e5ef963b9ad 100644 --- a/drivers/filesystems/npfs/rw.c +++ b/drivers/filesystems/npfs/rw.c @@ -51,7 +51,9 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject, PNPFS_DEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION IoStack; PNPFS_CCB Ccb; - BOOLEAN Complete = FALSE; + PLIST_ENTRY ListEntry; + PNPFS_THREAD_CONTEXT ThreadContext; + ULONG i; DPRINT("NpfsReadWriteCancelRoutine(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); @@ -67,28 +69,50 @@ NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject, switch(IoStack->MajorFunction) { case IRP_MJ_READ: - if (Ccb->ReadRequestListHead.Flink != &Context->ListEntry) + ListEntry = DeviceExt->ThreadListHead.Flink; + while (ListEntry != &DeviceExt->ThreadListHead) { - /* we are not the first in the list, remove an complete us */ - RemoveEntryList(&Context->ListEntry); - Complete = TRUE; - } - else - { - KeSetEvent(&Ccb->ReadEvent, IO_NO_INCREMENT, FALSE); + ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry); + /* Real events start at index 1 */ + for (i = 1; i < ThreadContext->Count; i++) + { + if (ThreadContext->WaitIrpArray[i] == Irp) + { + ASSERT(ThreadContext->WaitObjectArray[i] == Context->WaitEvent); + + ThreadContext->WaitIrpArray[i] = NULL; + + RemoveEntryList(&Context->ListEntry); + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE); + + ExReleaseFastMutex(&Ccb->DataListLock); + KeUnlockMutex(&DeviceExt->PipeListLock); + + return; + } + } + ListEntry = ListEntry->Flink; } + + RemoveEntryList(&Context->ListEntry); + + ExReleaseFastMutex(&Ccb->DataListLock); + KeUnlockMutex(&DeviceExt->PipeListLock); + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); break; default: ASSERT(FALSE); } - ExReleaseFastMutex(&Ccb->DataListLock); - KeUnlockMutex(&DeviceExt->PipeListLock); - if (Complete) - { - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } } static VOID NTAPI @@ -96,16 +120,11 @@ NpfsWaiterThread(PVOID InitContext) { PNPFS_THREAD_CONTEXT ThreadContext = (PNPFS_THREAD_CONTEXT) InitContext; ULONG CurrentCount; - ULONG Count = 0; + ULONG Count = 0, i; PIRP Irp = NULL; - PIRP NextIrp; NTSTATUS Status; - BOOLEAN Terminate = FALSE; - BOOLEAN Cancel = FALSE; PIO_STACK_LOCATION IoStack = NULL; - PNPFS_CONTEXT Context; - PNPFS_CONTEXT NextContext; - PNPFS_CCB Ccb; + KIRQL OldIrql; KeLockMutex(&ThreadContext->DeviceExt->PipeListLock); @@ -113,29 +132,23 @@ NpfsWaiterThread(PVOID InitContext) { CurrentCount = ThreadContext->Count; KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock); - if (Irp) + IoAcquireCancelSpinLock(&OldIrql); + if (Irp && IoSetCancelRoutine(Irp, NULL) != NULL) { - if (Cancel) + IoReleaseCancelSpinLock(OldIrql); + IoStack = IoGetCurrentIrpStackLocation(Irp); + switch (IoStack->MajorFunction) { - Irp->IoStatus.Status = STATUS_CANCELLED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - else - { - switch (IoStack->MajorFunction) - { case IRP_MJ_READ: NpfsRead(IoStack->DeviceObject, Irp); break; default: ASSERT(FALSE); - } } } - if (Terminate) + else { - break; + IoReleaseCancelSpinLock(OldIrql); } Status = KeWaitForMultipleObjects(CurrentCount, ThreadContext->WaitObjectArray, @@ -150,7 +163,7 @@ NpfsWaiterThread(PVOID InitContext) ASSERT(FALSE); } KeLockMutex(&ThreadContext->DeviceExt->PipeListLock); - Count = Status - STATUS_SUCCESS; + Count = Status - STATUS_WAIT_0; ASSERT (Count < CurrentCount); if (Count > 0) { @@ -159,47 +172,31 @@ NpfsWaiterThread(PVOID InitContext) ThreadContext->DeviceExt->EmptyWaiterCount++; ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count]; ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count]; - - Cancel = (NULL == IoSetCancelRoutine(Irp, NULL)); - Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext; - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (Cancel) - { - Ccb = IoStack->FileObject->FsContext2; - ExAcquireFastMutex(&Ccb->DataListLock); - RemoveEntryList(&Context->ListEntry); - switch (IoStack->MajorFunction) - { - case IRP_MJ_READ: - if (!IsListEmpty(&Ccb->ReadRequestListHead)) - { - /* put the next request on the wait list */ - NextContext = CONTAINING_RECORD(Ccb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry); - ThreadContext->WaitObjectArray[ThreadContext->Count] = NextContext->WaitEvent; - NextIrp = CONTAINING_RECORD(NextContext, IRP, Tail.Overlay.DriverContext); - ThreadContext->WaitIrpArray[ThreadContext->Count] = NextIrp; - ThreadContext->Count++; - ThreadContext->DeviceExt->EmptyWaiterCount--; - } - break; - default: - ASSERT(FALSE); - } - ExReleaseFastMutex(&Ccb->DataListLock); - } } else { - /* someone has add a new wait request */ + /* someone has add a new wait request or cancelled an old one */ Irp = NULL; + + /* Look for cancelled requests */ + for (i = 1; i < ThreadContext->Count; i++) + { + if (ThreadContext->WaitIrpArray[i] == NULL) + { + ThreadContext->Count--; + ThreadContext->DeviceExt->EmptyWaiterCount++; + ThreadContext->WaitObjectArray[i] = ThreadContext->WaitObjectArray[ThreadContext->Count]; + ThreadContext->WaitIrpArray[i] = ThreadContext->WaitIrpArray[ThreadContext->Count]; + } + } } if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS) { /* it exist an other thread with empty wait slots, we can remove our thread from the list */ RemoveEntryList(&ThreadContext->ListEntry); ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1; - Terminate = TRUE; + KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock); + break; } } ExFreePool(ThreadContext); @@ -332,10 +329,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject, if ((Ccb->OtherSide == NULL) && (Ccb->ReadDataAvailable == 0)) { if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE) - { - DPRINT("File pipe broken\n"); Status = STATUS_PIPE_BROKEN; - } else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE) Status = STATUS_PIPE_LISTENING; else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE) @@ -443,7 +437,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject, { break; } - if ((Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) && (Ccb->ReadDataAvailable == 0)) + if (((Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) || (!Ccb->OtherSide)) && (Ccb->ReadDataAvailable == 0)) { DPRINT("PipeState: %x\n", Ccb->PipeState); Status = STATUS_PIPE_BROKEN; @@ -787,7 +781,16 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, } Status = STATUS_SUCCESS; - Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + Buffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, NormalPagePriority); + + if (!Buffer) + { + DPRINT("MmGetSystemAddressForMdlSafe failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + Length = 0; + goto done; + + } ExAcquireFastMutex(&ReaderCcb->DataListLock); @@ -800,13 +803,13 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, { if ((ReaderCcb->WriteQuotaAvailable == 0)) { - KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE); - if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) + if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE || !Ccb->OtherSide) { Status = STATUS_PIPE_BROKEN; ExReleaseFastMutex(&ReaderCcb->DataListLock); goto done; } + KeSetEvent(&ReaderCcb->ReadEvent, IO_NO_INCREMENT, FALSE); ExReleaseFastMutex(&ReaderCcb->DataListLock); DPRINT("Write Waiting for buffer space (%S)\n", Fcb->PipeName.Buffer); @@ -830,20 +833,15 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject, * It's possible that the event was signaled because the * other side of pipe was closed. */ - if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE) + if (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE || !Ccb->OtherSide) { DPRINT("PipeState: %x\n", Ccb->PipeState); Status = STATUS_PIPE_BROKEN; goto done; } /* Check that the pipe has not been closed */ - if (ReaderCcb->PipeState != FILE_PIPE_CONNECTED_STATE) + if (ReaderCcb->PipeState != FILE_PIPE_CONNECTED_STATE || !ReaderCcb->OtherSide) { - /* If the other side is valid, fire event */ - if (Ccb) - { - KeResetEvent(&Ccb->WriteEvent); - } Status = STATUS_PIPE_BROKEN; goto done; } diff --git a/drivers/filesystems/npfs/volume.c b/drivers/filesystems/npfs/volume.c index 4241c88ec3d..63eb0773b91 100644 --- a/drivers/filesystems/npfs/volume.c +++ b/drivers/filesystems/npfs/volume.c @@ -23,12 +23,15 @@ NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo); if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) + { + *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION); return STATUS_BUFFER_OVERFLOW; + } FsDeviceInfo->DeviceType = FILE_DEVICE_NAMED_PIPE; FsDeviceInfo->Characteristics = 0; - *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION); + *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION); DPRINT("NpfsQueryFsDeviceInformation() finished.\n"); @@ -44,7 +47,10 @@ NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo); if (*BufferLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8) + { + *BufferLength = (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); return STATUS_BUFFER_OVERFLOW; + } FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES; FsAttributeInfo->MaximumComponentNameLength = 255; @@ -53,7 +59,7 @@ NpfsQueryFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, L"NPFS"); DPRINT("NpfsQueryFsAttributeInformation() finished.\n"); - *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); + *BufferLength = (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); return STATUS_SUCCESS; } @@ -102,10 +108,8 @@ NpfsQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, } Irp->IoStatus.Status = Status; - if (NT_SUCCESS(Status)) - Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength; - else - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = BufferLength; + IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/drivers/ksfilter/ks/pin.c b/drivers/ksfilter/ks/pin.c index 019e5ce6023..a95755c2279 100644 --- a/drivers/ksfilter/ks/pin.c +++ b/drivers/ksfilter/ks/pin.c @@ -1332,7 +1332,9 @@ IKsPin_PrepareStreamHeader( else StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetOut; +#ifndef _WIN64 StreamPointer->StreamPointer.Offset->Alignment = 0; +#endif StreamPointer->StreamPointer.Offset->Count = 0; StreamPointer->StreamPointer.Offset->Data = NULL; StreamPointer->StreamPointer.Offset->Remaining = 0; @@ -1352,7 +1354,9 @@ IKsPin_PrepareStreamHeader( /* FIXME */ ASSERT(Length); +#ifndef _WIN64 StreamPointer->StreamPointer.Offset->Alignment = 0; +#endif StreamPointer->StreamPointer.Context = NULL; StreamPointer->StreamPointer.Pin = &This->Pin; StreamPointer->StreamPointer.Offset->Count = Length; @@ -1543,7 +1547,7 @@ KsStreamPointerClone( IKsPinImpl * This; PKSISTREAM_POINTER CurFrame; PKSISTREAM_POINTER NewFrame; - ULONG RefCount; + ULONG_PTR RefCount; NTSTATUS Status; ULONG Size; @@ -1562,7 +1566,7 @@ KsStreamPointerClone( return STATUS_INSUFFICIENT_RESOURCES; /* get current irp stack location */ - RefCount = (ULONG)CurFrame->Irp->Tail.Overlay.DriverContext[0]; + RefCount = (ULONG_PTR)CurFrame->Irp->Tail.Overlay.DriverContext[0]; /* increment reference count */ RefCount++; diff --git a/drivers/network/afd/afd/connect.c b/drivers/network/afd/afd/connect.c index 3f47a05941a..28fcfada857 100644 --- a/drivers/network/afd/afd/connect.c +++ b/drivers/network/afd/afd/connect.c @@ -247,6 +247,8 @@ NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB ) { if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND; + FCB->PollStatus[FD_CONNECT_BIT] = STATUS_SUCCESS; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); return Status; @@ -291,6 +293,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete if( !NT_SUCCESS(Irp->IoStatus.Status) ) { FCB->PollState |= AFD_EVENT_CONNECT_FAIL; + FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status; AFD_DbgPrint(MID_TRACE,("Going to bound state\n")); FCB->State = SOCKET_STATE_BOUND; PollReeval( FCB->DeviceExt, FCB->FileObject ); diff --git a/drivers/network/afd/afd/listen.c b/drivers/network/afd/afd/listen.c index 5a1b8f55bbb..f6eb1104210 100644 --- a/drivers/network/afd/afd/listen.c +++ b/drivers/network/afd/afd/listen.c @@ -193,11 +193,10 @@ static NTSTATUS NTAPI ListenComplete /* Trigger a select return if appropriate */ if( !IsListEmpty( &FCB->PendingConnections ) ) { FCB->PollState |= AFD_EVENT_ACCEPT; - } else { - FCB->PollState &= ~AFD_EVENT_ACCEPT; - } - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); @@ -293,12 +292,13 @@ NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n")); - if ( IsListEmpty( &FCB->PendingConnections ) ) - FCB->PollState &= ~AFD_EVENT_ACCEPT; - else + if ( !IsListEmpty( &FCB->PendingConnections ) ) + { FCB->PollState |= AFD_EVENT_ACCEPT; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); return Status; @@ -402,13 +402,12 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( PendingConnObj ); - if( IsListEmpty( &FCB->PendingConnections ) ) { - FCB->PollState &= ~AFD_EVENT_ACCEPT; - } else { + if( !IsListEmpty( &FCB->PendingConnections ) ) { FCB->PollState |= AFD_EVENT_ACCEPT; - } - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); return Status; diff --git a/drivers/network/afd/afd/main.c b/drivers/network/afd/afd/main.c index bcbb2f56603..95da3c054bf 100644 --- a/drivers/network/afd/afd/main.c +++ b/drivers/network/afd/afd/main.c @@ -314,6 +314,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* A datagram socket is always sendable */ FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } @@ -377,6 +378,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->State = SOCKET_STATE_CLOSED; FCB->PollState = AFD_EVENT_CLOSE; + FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; //I think we can return success here PollReeval( FCB->DeviceExt, FCB->FileObject ); InFlightRequest[0] = &FCB->ListenIrp; @@ -542,6 +544,7 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( ConnectionReturnInfo ); FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } else Status = STATUS_INVALID_PARAMETER; diff --git a/drivers/network/afd/afd/read.c b/drivers/network/afd/afd/read.c index dccfa559ba8..f98fd17b3aa 100644 --- a/drivers/network/afd/afd/read.c +++ b/drivers/network/afd/afd/read.c @@ -46,6 +46,7 @@ static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) { { /* The socket has been closed */ FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollStatus[FD_CLOSE_BIT] = Status; FCB->Overread = TRUE; Status = STATUS_FILE_CLOSED; } @@ -53,6 +54,7 @@ static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) { { FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; FCB->PollState |= AFD_EVENT_RECEIVE; + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; } PollReeval( FCB->DeviceExt, FCB->FileObject ); } @@ -189,10 +191,10 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { if( FCB->Recv.Content ) { FCB->PollState |= AFD_EVENT_RECEIVE; + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } else - FCB->PollState &= ~AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollState &= ~AFD_EVENT_RECEIVE; AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus)); @@ -538,10 +540,10 @@ PacketSocketRecvComplete( if( !IsListEmpty( &FCB->DatagramList ) ) { AFD_DbgPrint(MID_TRACE,("Signalling\n")); FCB->PollState |= AFD_EVENT_RECEIVE; + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } else - FCB->PollState &= ~AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollState &= ~AFD_EVENT_RECEIVE; if( NT_SUCCESS(Irp->IoStatus.Status) ) { /* Now relaunch the datagram request */ @@ -608,12 +610,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = DatagramRecv->Len; - if( IsListEmpty( &FCB->DatagramList ) ) - FCB->PollState &= ~AFD_EVENT_RECEIVE; - else + if( !IsListEmpty( &FCB->DatagramList ) ) { FCB->PollState |= AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_RECEIVE; UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); @@ -624,12 +626,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, ( FCB, Irp, DatagramRecv, (PUINT)&Irp->IoStatus.Information ); - if( IsListEmpty( &FCB->DatagramList ) ) - FCB->PollState &= ~AFD_EVENT_RECEIVE; - else + if( !IsListEmpty( &FCB->DatagramList ) ) { FCB->PollState |= AFD_EVENT_RECEIVE; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } else + FCB->PollState &= ~AFD_EVENT_RECEIVE; UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); @@ -640,12 +642,10 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); Status = STATUS_CANT_WAIT; FCB->PollState &= ~AFD_EVENT_RECEIVE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE ); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } else { FCB->PollState &= ~AFD_EVENT_RECEIVE; - PollReeval( FCB->DeviceExt, FCB->FileObject ); return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV ); } } diff --git a/drivers/network/afd/afd/select.c b/drivers/network/afd/afd/select.c index 4cdbcdffb4a..dd334d343a8 100644 --- a/drivers/network/afd/afd/select.c +++ b/drivers/network/afd/afd/select.c @@ -296,8 +296,11 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->EventSelect = NULL; else FCB->EventSelectTriggers = EventSelectInfo->Events; - } else - Status = STATUS_INVALID_PARAMETER; + } else { + FCB->EventSelect = NULL; + FCB->EventSelectTriggers = 0; + Status = STATUS_SUCCESS; + } AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); @@ -325,7 +328,9 @@ AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp, } EnumReq->PollEvents = FCB->PollState; - RtlZeroMemory( EnumReq->EventStatus, sizeof(EnumReq->EventStatus) ); + RtlCopyMemory( EnumReq->EventStatus, + FCB->PollStatus, + sizeof(EnumReq->EventStatus) ); return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 ); diff --git a/drivers/network/afd/afd/write.c b/drivers/network/afd/afd/write.c index aa1c9e371a5..7506489be8e 100644 --- a/drivers/network/afd/afd/write.c +++ b/drivers/network/afd/afd/write.c @@ -142,10 +142,10 @@ static NTSTATUS NTAPI SendComplete FCB ); } else { FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } - PollReeval( FCB->DeviceExt, FCB->FileObject ); - if( TotalBytesCopied > 0 ) { UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); @@ -186,6 +186,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete /* Request is not in flight any longer */ FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); if( FCB->State == SOCKET_STATE_CLOSED ) { @@ -391,10 +392,6 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); - FCB->PollState &= ~AFD_EVENT_SEND; - - PollReeval( FCB->DeviceExt, FCB->FileObject ); - /* Check that the socket is bound */ if( FCB->State != SOCKET_STATE_BOUND ) return UnlockAndMaybeComplete @@ -425,6 +422,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* Check the size of the Address given ... */ if( NT_SUCCESS(Status) ) { + FCB->PollState &= ~AFD_EVENT_SEND; + Status = TdiSendDatagram ( &FCB->SendIrp.InFlightRequest, FCB->AddressFile.Object, diff --git a/drivers/network/afd/include/afd.h b/drivers/network/afd/include/afd.h index 6b5e875ec9b..ac3a286cd6c 100644 --- a/drivers/network/afd/include/afd.h +++ b/drivers/network/afd/include/afd.h @@ -192,6 +192,7 @@ typedef struct _AFD_FCB { UNICODE_STRING TdiDeviceName; PVOID Context; DWORD PollState; + NTSTATUS PollStatus[FD_MAX_EVENTS]; UINT ContextSize; PVOID ConnectData; UINT FilledConnectData; diff --git a/drivers/network/ndis/ndis/memory.c b/drivers/network/ndis/ndis/memory.c index 7696389e876..3d96170ea4c 100644 --- a/drivers/network/ndis/ndis/memory.c +++ b/drivers/network/ndis/ndis/memory.c @@ -171,6 +171,15 @@ NdisMAllocateSharedMemory( NDIS_DbgPrint(MAX_TRACE,("Called.\n")); + if (KeGetCurrentIrql() != PASSIVE_LEVEL) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)MiniportAdapterHandle, + Length, + 0, + 1); + } + *VirtualAddress = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->AllocateCommonBuffer( Adapter->NdisMiniportBlock.SystemAdapterObject, Length, PhysicalAddress, Cached); } diff --git a/drivers/network/ndis/ndis/miniport.c b/drivers/network/ndis/ndis/miniport.c index daaf7cac1b1..4492caffe32 100644 --- a/drivers/network/ndis/ndis/miniport.c +++ b/drivers/network/ndis/ndis/miniport.c @@ -365,6 +365,15 @@ MiniResetComplete( KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + if (Adapter->NdisMiniportBlock.ResetStatus != NDIS_STATUS_PENDING) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)MiniportAdapterHandle, + (ULONG_PTR)Status, + (ULONG_PTR)AddressingReset, + 0); + } + Adapter->NdisMiniportBlock.ResetStatus = Status; CurrentEntry = Adapter->ProtocolListHead.Flink; @@ -1959,6 +1968,22 @@ NdisIPnPStartDevice( { NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n")); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); + if (Adapter->NdisMiniportBlock.Interrupt) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)Adapter, + (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt, + (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue, + 1); + } + if (Adapter->NdisMiniportBlock.TimerQueue) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)Adapter, + (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt, + (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue, + 1); + } return NdisStatus; } diff --git a/drivers/network/ndis/ndis/time.c b/drivers/network/ndis/ndis/time.c index 75a65f3b24f..0e8cdd46473 100644 --- a/drivers/network/ndis/ndis/time.c +++ b/drivers/network/ndis/ndis/time.c @@ -95,6 +95,38 @@ NdisInitializeTimer( KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext); } +BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) +{ + PNDIS_MINIPORT_TIMER CurrentTimer; + + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + if (!Timer->Miniport->TimerQueue) + return FALSE; + + if (Timer->Miniport->TimerQueue == Timer) + { + Timer->Miniport->TimerQueue = Timer->NextDeferredTimer; + Timer->NextDeferredTimer = NULL; + return TRUE; + } + else + { + CurrentTimer = Timer->Miniport->TimerQueue; + while (CurrentTimer->NextDeferredTimer) + { + if (CurrentTimer->NextDeferredTimer == Timer) + { + CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer; + Timer->NextDeferredTimer = NULL; + return TRUE; + } + CurrentTimer = CurrentTimer->NextDeferredTimer; + } + return FALSE; + } +} + /* * @implemented @@ -113,11 +145,44 @@ NdisMCancelTimer( * - call at IRQL <= DISPATCH_LEVEL */ { + KIRQL OldIrql; + ASSERT_IRQL(DISPATCH_LEVEL); ASSERT(TimerCancelled); ASSERT(Timer); *TimerCancelled = KeCancelTimer (&Timer->Timer); + + if (*TimerCancelled) + { + KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); + /* If it's somebody already dequeued it, something is wrong (maybe a double-cancel?) */ + if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE); + KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); + } +} + +VOID NTAPI +MiniTimerDpcFunction(PKDPC Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + PNDIS_MINIPORT_TIMER Timer = DeferredContext; + + Timer->MiniportTimerFunction(Dpc, + Timer->MiniportTimerContext, + SystemArgument1, + SystemArgument2); + + /* Only dequeue if the timer has a period of 0 */ + if (!Timer->Timer.Period) + { + KeAcquireSpinLockAtDpcLevel(&Timer->Miniport->Lock); + /* If someone already dequeued it, something is wrong (borked timer implementation?) */ + if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE); + KeReleaseSpinLockFromDpcLevel(&Timer->Miniport->Lock); + } } @@ -145,9 +210,14 @@ NdisMInitializeTimer( { PAGED_CODE(); ASSERT(Timer); - KeInitializeTimer (&Timer->Timer); - KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext); + KeInitializeTimer (&Timer->Timer); + KeInitializeDpc (&Timer->Dpc, MiniTimerDpcFunction, Timer); + + Timer->MiniportTimerFunction = TimerFunction; + Timer->MiniportTimerContext = FunctionContext; + Timer->Miniport = &((PLOGICAL_ADAPTER)MiniportAdapterHandle)->NdisMiniportBlock; + Timer->NextDeferredTimer = NULL; } @@ -170,6 +240,7 @@ NdisMSetPeriodicTimer( */ { LARGE_INTEGER Timeout; + KIRQL OldIrql; ASSERT_IRQL(DISPATCH_LEVEL); ASSERT(Timer); @@ -177,7 +248,15 @@ NdisMSetPeriodicTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000); - KeSetTimerEx (&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc); + KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); + /* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */ + if (!KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc)) + { + /* Add the timer at the head of the timer queue */ + Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; + Timer->Miniport->TimerQueue = Timer; + } + KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); } @@ -201,6 +280,7 @@ NdisMSetTimer( */ { LARGE_INTEGER Timeout; + KIRQL OldIrql; ASSERT_IRQL(DISPATCH_LEVEL); ASSERT(Timer); @@ -208,7 +288,15 @@ NdisMSetTimer( /* relative delays are negative, absolute are positive; resolution is 100ns */ Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000); - KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc); + KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); + /* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */ + if (!KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc)) + { + /* Add the timer at the head of the timer queue */ + Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; + Timer->Miniport->TimerQueue = Timer; + } + KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); } diff --git a/drivers/network/tcpip/tcpip/fileobjs.c b/drivers/network/tcpip/tcpip/fileobjs.c index bd7968e5ede..70357fced9a 100644 --- a/drivers/network/tcpip/tcpip/fileobjs.c +++ b/drivers/network/tcpip/tcpip/fileobjs.c @@ -265,7 +265,7 @@ NTSTATUS FileOpenAddress( !AddrLocateInterface(&AddrFile->Address)) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address))); - return STATUS_INVALID_PARAMETER; + return STATUS_INVALID_ADDRESS; } TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n", @@ -282,7 +282,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); - return STATUS_INVALID_PARAMETER; + return STATUS_ADDRESS_ALREADY_EXISTS; } AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP); @@ -300,7 +300,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); - return STATUS_INVALID_PARAMETER; + return STATUS_ADDRESS_ALREADY_EXISTS; } TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n", diff --git a/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp b/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp index edf88bf746e..a3d884dc912 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp +++ b/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp @@ -29,7 +29,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "adapter.hpp" -//#pragma code_seg("PAGE") +#ifdef _MSC_VER +//#pragma code_seg("PAGE") // GCC ignores pragma code_seg +#endif const GUID KSNODETYPE_DAC = {0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; const GUID KSNODETYPE_ADC = {0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; @@ -267,7 +269,9 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour PUNKNOWN unknownTopology = NULL; // install the topology miniport. - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Topology", CLSID_PortTopology, CLSID_PortTopology, CreateMiniportTopologyCMI, pCMIAdapter, NULL, GUID_NULL, &unknownTopology); + ntStatus = InstallSubdevice( DeviceObject, Irp, (PWCHAR) L"Topology", + CLSID_PortTopology, CLSID_PortTopology, CreateMiniportTopologyCMI, + pCMIAdapter, NULL, GUID_NULL, &unknownTopology ); if (!NT_SUCCESS (ntStatus)) { DBGPRINT(("Topology miniport installation failed")); return ntStatus; @@ -277,7 +281,7 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour // install the UART miniport - execution order important ntStatus = STATUS_UNSUCCESSFUL; MPUBase = 0; - for (int i=0;iNumberOfPorts();i++) { + for ( UINT i=0; i < ResourceList->NumberOfPorts(); i++ ) { if (ResourceList->FindTranslatedPort(i)->u.Port.Length == 2) { MPUBase = (UInt32*)ResourceList->FindTranslatedPort(i)->u.Port.Start.QuadPart; } @@ -285,7 +289,10 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour if (MPUBase != 0) { ntStatus = pCMIAdapter->activateMPU(MPUBase); if (NT_SUCCESS(ntStatus)) { - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Uart", CLSID_PortDMus, CLSID_MiniportDriverDMusUART, NULL, pCMIAdapter->getInterruptSync(), UartResourceList, IID_IPortDMus, NULL); + ntStatus = InstallSubdevice( DeviceObject, Irp, (PWCHAR) L"Uart", + CLSID_PortDMus, CLSID_MiniportDriverDMusUART, NULL, + pCMIAdapter->getInterruptSync(), UartResourceList, + IID_IPortDMus, NULL ); } } if (!NT_SUCCESS(ntStatus)) { @@ -300,9 +307,13 @@ NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST Resour // install the wave miniport - the order matters here #ifdef WAVERT - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Wave", CLSID_PortWaveRT, CLSID_PortWaveRT, CreateMiniportWaveCMI, pCMIAdapter, ResourceList, IID_IPortWaveRT, &unknownWave); + ntStatus = InstallSubdevice(DeviceObject, Irp, (PWCHAR) L"Wave", + CLSID_PortWaveRT, CLSID_PortWaveRT, CreateMiniportWaveCMI, + pCMIAdapter, ResourceList, IID_IPortWaveRT, &unknownWave ); #else - ntStatus = InstallSubdevice(DeviceObject, Irp, L"Wave", CLSID_PortWaveCyclic, CLSID_PortWaveCyclic, CreateMiniportWaveCMI, pCMIAdapter, ResourceList, IID_IPortWaveCyclic, &unknownWave); + ntStatus = InstallSubdevice(DeviceObject, Irp, (PWCHAR) L"Wave", + CLSID_PortWaveCyclic, CLSID_PortWaveCyclic, CreateMiniportWaveCMI, + pCMIAdapter, ResourceList, IID_IPortWaveCyclic, &unknownWave ); #endif if (!NT_SUCCESS(ntStatus)) { DBGPRINT(("Wave miniport installation failed")); @@ -449,8 +460,10 @@ AdapterDispatchPnp( resourceList->List[0].Count = 0; // copy the resources which have already been assigned - for (int i=0;iList[0].Count;i++) { - if (CopyResourceDescriptor(&list->List[0].Descriptors[i], &resourceList->List[0].Descriptors[resourceList->List[0].Count])) { + for ( UINT i=0; i < list->List[0].Count; i++ ) { + if (CopyResourceDescriptor( &list->List[0].Descriptors[i], + &resourceList->List[0].Descriptors[resourceList->List[0].Count] )) + { resourceList->List[0].Count++; } } diff --git a/drivers/wdm/audio/drivers/CMIDriver/common.cpp b/drivers/wdm/audio/drivers/CMIDriver/common.cpp index 260f51d62e2..dc2b62ac55e 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/common.cpp +++ b/drivers/wdm/audio/drivers/CMIDriver/common.cpp @@ -27,7 +27,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common.hpp" -#pragma code_seg("PAGE") +#ifdef _MSC_VER +#pragma code_seg("PAGE") /* warning - ignored by GCC compiler */ +#endif NTSTATUS NewCMIAdapter( @@ -63,7 +65,7 @@ STDMETHODIMP_(NTSTATUS) CCMIAdapter::init(PRESOURCELIST ResourceList, PDEVICE_OB DeviceObject = aDeviceObject; cm.IOBase = 0; - for (int i=0;iNumberOfPorts();i++) { + for ( UINT i=0; i < ResourceList->NumberOfPorts(); i++ ) { if (ResourceList->FindTranslatedPort(i)->u.Port.Length == 0x100) { cm.IOBase = (UInt32*)ResourceList->FindTranslatedPort(i)->u.Port.Start.QuadPart; } @@ -357,7 +359,7 @@ STDMETHODIMP_(NTSTATUS) CCMIAdapter::loadSBMixerFromMemory() //PAGED_CODE(); DBGPRINT(("CCMIAdapter[%p]::loadSBMixerFromMemory()", this)); #endif - for (int i = 0; i<(sizeof(sbIndex)/sizeof(sbIndex[0]));i++) { + for ( UINT i = 0; i < (sizeof(sbIndex)/sizeof(sbIndex[0])); i++ ) { writeUInt8(REG_SBINDEX, sbIndex[i]); writeUInt8(REG_SBDATA, mixerCache[i]); } @@ -368,7 +370,9 @@ STDMETHODIMP_(NTSTATUS) CCMIAdapter::loadSBMixerFromMemory() /* ** non-paged code below */ -#pragma code_seg() +#ifdef _MSC_VER +#pragma code_seg() /* warning - ignored by GCC compiler */ +#endif STDMETHODIMP_(UInt8) CCMIAdapter::readUInt8(UInt8 reg) { diff --git a/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp b/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp index 23584dd1dcd..283dc2b071f 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp +++ b/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp @@ -31,7 +31,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define NTSTRSAFE_LIB //for Windows 2000 compatibility #include "ntstrsafe.h" -#pragma code_seg("PAGE") +#ifdef _MSC_VER +#pragma code_seg("PAGE") /* warning - ignored by GCC compiler */ +#endif const GUID KSPROPSETID_CMI = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}}; @@ -173,7 +175,7 @@ STDMETHODIMP CCMITopology::loadMixerSettingsFromRegistry() PropertyRequest.ValueSize = sizeof(DWORD); PropertyRequest.PropertyItem = &PropertyItem; - for (int i=0;i < SIZEOF_ARRAY(TopologyNodes); i++) { + for ( UINT i=0; i < SIZEOF_ARRAY(TopologyNodes); i++ ) { PropertyRequest.Node = i; Channel = CHAN_LEFT; @@ -310,7 +312,7 @@ STDMETHODIMP CCMITopology::storeMixerSettingsToRegistry() PropertyRequest.ValueSize = sizeof(DWORD); PropertyRequest.PropertyItem = &PropertyItem; - for (int i=0;i < SIZEOF_ARRAY(TopologyNodes); i++) { + for ( UINT i=0; i < SIZEOF_ARRAY(TopologyNodes); i++ ) { PropertyRequest.Node = i; if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_VOLUME)) { PropertyRequest.Node = i; @@ -473,7 +475,8 @@ NTSTATUS NTAPI PropertyHandler_OnOff(PPCPROPERTY_REQUEST PropertyRequest) CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget); NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; - UInt8 data, mask, reg; + //UInt8 data, mask, reg; + UInt8 mask, reg; LONG channel; if (PropertyRequest->Node == ULONG(-1)) { @@ -1042,7 +1045,7 @@ static NTSTATUS BasicSupportHandler(PPCPROPERTY_REQUEST PropertyRequest) PKSPROPERTY_STEPPING_LONG Range = PKSPROPERTY_STEPPING_LONG(Members + 1); - for (int i=0;iNode) { Range->Bounds.SignedMaximum = (VolTable[i].max << 16); Range->Bounds.SignedMinimum = (VolTable[i].min << 16); @@ -1110,7 +1113,7 @@ NTSTATUS NTAPI PropertyHandler_Level(PPCPROPERTY_REQUEST PropertyRequest) PLONG Level = (PLONG)PropertyRequest->Value; - for (int i=0;iNode) { if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) { diff --git a/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp b/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp index dce93b1cf44..182b4e6d97f 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp +++ b/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp @@ -35,7 +35,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF\ DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF) DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF); -#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) +#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED( KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF ) +/* Warning - Recursive #define for KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF */ #endif #endif @@ -47,15 +48,17 @@ NTSTATUS NTAPI PropertyHandler_Private(PPCPROPERTY_REQUEST PropertyRequest); static KSDATARANGE PinDataRangesBridge[] = { - { - sizeof(KSDATARANGE), - 0, - 0, - 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) - } + { + { + sizeof(KSDATARANGE), + 0, + 0, + 0, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + } + } }; static PKSDATARANGE PinDataRangePointersBridge[] = @@ -65,14 +68,16 @@ static PKSDATARANGE PinDataRangePointersBridge[] = static KSDATARANGE WavePinDataRangesAC3Bridge[] = { - { - sizeof(KSDATARANGE), - 0, - 0, - 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) + { + { + sizeof(KSDATARANGE), + 0, + 0, + 0, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + } } }; @@ -98,7 +103,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSCATEGORY_AUDIO, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -117,7 +122,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_SPDIF_INTERFACE, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -136,7 +141,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_MICROPHONE, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -155,7 +160,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_CD_PLAYER, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -174,7 +179,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_LINE_CONNECTOR, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -193,7 +198,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_ANALOG_CONNECTOR, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -212,7 +217,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_ANALOG_CONNECTOR, // Category &CMINAME_DAC, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -231,7 +236,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSNODETYPE_SPEAKER, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -250,7 +255,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSCATEGORY_AUDIO, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -269,7 +274,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication &KSCATEGORY_AUDIO, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } }, @@ -288,7 +293,7 @@ static PCPIN_DESCRIPTOR MiniportPins[] = KSPIN_COMMUNICATION_NONE, // Communication NULL, // Category NULL, // Name - 0 // Reserved + { 0 } // Reserved } } }; diff --git a/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp b/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp index 4a0477133d5..5152d863e57 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp +++ b/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp @@ -29,7 +29,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "minwavetables.hpp" #include "ntddk.h" -#pragma code_seg("PAGE") +#ifdef _MSC_VER +#pragma code_seg("PAGE") /* warning - ignored by GCC compiler */ +#endif HRESULT NTAPI CreateMiniportWaveCMI(PUNKNOWN *Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) { @@ -233,7 +235,8 @@ NTSTATUS CMiniportWaveCMI::loadChannelConfigFromRegistry() PREGISTRYKEY DriverKey; PREGISTRYKEY SettingsKey; UNICODE_STRING KeyName; - DWORD Value, ResultLength; + //DWORD Value, ResultLength; + DWORD ResultLength; PVOID KeyInfo; DBGPRINT(("CMiniportWaveCMI::loadChannelConfigFromRegistry()")); @@ -418,12 +421,12 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO DBGPRINT(("---channels: %d, resolution: %d, sample rate: %d, pin: %d, formatMask: %x", waveFormat->nChannels, waveFormat->wBitsPerSample, waveFormat->nSamplesPerSec, PinID, cm->formatMask)); //WaveFormatEx - if ( ( format->FormatSize >= sizeof(KSDATAFORMAT_WAVEFORMATEX)) + if ( ( (size_t) format->FormatSize >= sizeof(KSDATAFORMAT_WAVEFORMATEX)) && IsEqualGUIDAligned(format->MajorFormat,KSDATAFORMAT_TYPE_AUDIO) && IsEqualGUIDAligned(format->Specifier,KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) ) { switch (EXTRACT_WAVEFORMATEX_ID(&format->SubFormat)) { case WAVE_FORMAT_PCM: - if ((PinID != PIN_WAVE_RENDER_SINK) && (PinID != PIN_WAVE_CAPTURE_SOURCE) && (PinID != -1)) { + if ((PinID != PIN_WAVE_RENDER_SINK) && (PinID != PIN_WAVE_CAPTURE_SOURCE) && ((int)PinID != -1)) { if ((PinID == PIN_WAVE_AC3_RENDER_SINK) && !IoIsWdmVersionAvailable(6,0)) { return STATUS_INVALID_PARAMETER; } @@ -438,10 +441,10 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO return isFormatAllowed(waveFormat->nSamplesPerSec, FALSE, FALSE); } if ( (waveFormat->wBitsPerSample == 16) - && ((waveFormat->nChannels >= 4) && (waveFormat->nChannels <= cm->maxChannels)) + && ((waveFormat->nChannels >= 4) && (waveFormat->nChannels <= (WORD) cm->maxChannels)) && ((waveFormat->nSamplesPerSec == 44100) || (waveFormat->nSamplesPerSec == 48000)) ) { #if OUT_CHANNEL == 1 - if ((PinID == PIN_WAVE_RENDER_SINK) || (PinID == -1)) { + if ((PinID == PIN_WAVE_RENDER_SINK) || ((int)PinID == -1)) { return isFormatAllowed(waveFormat->nSamplesPerSec, TRUE, FALSE); } #else @@ -450,7 +453,7 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO } break; case WAVE_FORMAT_DOLBY_AC3_SPDIF: - if ((PinID != PIN_WAVE_AC3_RENDER_SINK) && (PinID != -1)) { + if ((PinID != PIN_WAVE_AC3_RENDER_SINK) && ((int)PinID != -1)) { return STATUS_INVALID_PARAMETER; } if ( ((waveFormat->wBitsPerSample >= MIN_BITS_PER_SAMPLE_AC3) && (waveFormat->wBitsPerSample <= MAX_BITS_PER_SAMPLE_AC3)) @@ -907,7 +910,7 @@ NTSTATUS CMiniportWaveStreamCMI::prepareStream() DBGPRINT(("---streamIndex: %d, channelNumber: %d", streamIndex, channelNumber)); NTSTATUS ntStatus; - UInt8 reg; + //UInt8 reg; UInt32 val; if (state == KSSTATE_RUN) { @@ -990,7 +993,7 @@ NTSTATUS CMiniportWaveStreamCMI::setDACChannels() NTSTATUS ntStatus = STATUS_SUCCESS; if (currentChannelCount > 2) { - if (Miniport->cm->maxChannels < currentChannelCount) { + if ((WORD) Miniport->cm->maxChannels < currentChannelCount ) { return STATUS_INVALID_DEVICE_REQUEST; } if ((currentResolution != 16) || (currentChannelCount < 2)) { @@ -1052,7 +1055,7 @@ NTSTATUS CMiniportWaveStreamCMI::setupSPDIFPlayback(bool enableSPDIF) //PAGED_CODE(); DBGPRINT(("CMiniportWaveStreamCMI[%p]::setupSPDIFPlayback(%d)", this, enableSPDIF)); - NTSTATUS ntStatus; + //NTSTATUS ntStatus; KeWaitForSingleObject(&Miniport->mutex, Executive, KernelMode, false, NULL); @@ -1434,7 +1437,9 @@ STDMETHODIMP_(NTSTATUS) CMiniportWaveStreamCMI::GetClockRegister(PKSRTAUDIO_HWRE /* ** non-paged code below */ -#pragma code_seg() +#ifdef _MSC_VER +#pragma code_seg() /* warning - ignored by GCC compiler */ +#endif STDMETHODIMP CMiniportWaveStreamCMI::SetState(KSSTATE NewState) { @@ -1461,7 +1466,9 @@ STDMETHODIMP CMiniportWaveStreamCMI::SetState(KSSTATE NewState) // STOP -> ACQUIRE -> PAUSE -> PLAY -> PAUSE -> ACQUIRE -> STOP if (state != NewState) { - switch (NewState) { + switch ((UINT) NewState) { + // LN: The cast on NewState is to satisfy the compiler about + // KSSTATE_STOP_AC3, which is not in the original enum KSSTATE. case KSSTATE_ACQUIRE: DBGPRINT(("---KSSTATE_ACQUIRE: previous state: %d", state)); if (state == KSSTATE_PAUSE) { diff --git a/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp b/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp index 0c0326ca21c..8f44c5a977d 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp +++ b/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp @@ -31,23 +31,23 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF\ DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF) DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF); -#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) +#define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) +/* Warning - Recursive #define for KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF */ NTSTATUS NTAPI PropertyHandler_ChannelConfig(PPCPROPERTY_REQUEST PropertyRequest); - static KSDATARANGE_AUDIO WavePinDataRangesPCMStream[] = { { - { + {{ sizeof(KSDATARANGE_AUDIO), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) - }, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) } + }}, MAX_CHANNELS_PCM, MIN_BITS_PER_SAMPLE_PCM, MAX_BITS_PER_SAMPLE_PCM, @@ -59,15 +59,15 @@ static KSDATARANGE_AUDIO WavePinDataRangesPCMStream[] = static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[] = { { - { + {{ sizeof(KSDATARANGE_AUDIO), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) - }, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) } + }}, MAX_CHANNELS_AC3, MIN_BITS_PER_SAMPLE_AC3, MAX_BITS_PER_SAMPLE_AC3, @@ -75,15 +75,15 @@ static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[] = MAX_SAMPLE_RATE_AC3 }, { - { + {{ sizeof(KSDATARANGE_AUDIO), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND) - }, + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_DSOUND) } + }}, MAX_CHANNELS_AC3, MIN_BITS_PER_SAMPLE_AC3, MAX_BITS_PER_SAMPLE_AC3, @@ -107,28 +107,28 @@ static PKSDATARANGE WavePinDataRangePointersAC3Stream[] = static KSDATARANGE WavePinDataRangesPCMBridge[] = { - { + {{ sizeof(KSDATARANGE), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) - } + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + }} }; static KSDATARANGE WavePinDataRangesAC3Bridge[] = { - { + {{ sizeof(KSDATARANGE), 0, 0, 0, - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) - } + { STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) }, + { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) } + }} }; static PKSDATARANGE WavePinDataRangePointersPCMBridge[] = @@ -160,7 +160,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_SINK, &KSCATEGORY_AUDIO, &KSAUDFNAME_RECORDING_CONTROL, - 0 + { 0 } } }, @@ -181,7 +181,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_NONE, &KSCATEGORY_AUDIO, NULL, - 0 + { 0 } } }, @@ -202,7 +202,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_SINK, &KSCATEGORY_AUDIO, &KSAUDFNAME_VOLUME_CONTROL, - 0 + { 0 } } }, @@ -223,7 +223,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_NONE, &KSNODETYPE_SPEAKER, NULL, - 0 + { 0 } } }, @@ -244,7 +244,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_SINK, &KSCATEGORY_AUDIO, NULL, - 0 + { 0 } } }, @@ -266,7 +266,7 @@ static PCPIN_DESCRIPTOR WaveMiniportPins[] = KSPIN_COMMUNICATION_NONE, &KSNODETYPE_SPDIF_INTERFACE, NULL, - 0 + { 0 } } } }; diff --git a/hal/halx86/amd64/halinit.c b/hal/halx86/amd64/halinit.c new file mode 100644 index 00000000000..b9b305126d3 --- /dev/null +++ b/hal/halx86/amd64/halinit.c @@ -0,0 +1,31 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/amd64/halinit.c + * PURPOSE: HAL Entrypoint and Initialization + * PROGRAMMERS: + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +/* PRIVATE FUNCTIONS *********************************************************/ + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalInitSystem(IN ULONG BootPhase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + UNIMPLEMENTED; + return FALSE; +} diff --git a/hal/halx86/mp/amd64/mps.S b/hal/halx86/amd64/mps.S similarity index 100% rename from hal/halx86/mp/amd64/mps.S rename to hal/halx86/amd64/mps.S diff --git a/hal/halx86/amd64/processor.c b/hal/halx86/amd64/processor.c new file mode 100644 index 00000000000..255f50b8bf0 --- /dev/null +++ b/hal/halx86/amd64/processor.c @@ -0,0 +1,97 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/amd64/processor.c + * PURPOSE: HAL Processor Routines + * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +KAFFINITY HalpActiveProcessors; +KAFFINITY HalpDefaultInterruptAffinity; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +HaliHaltSystem(VOID) +{ + /* Disable interrupts and halt the CPU */ + _disable(); + __halt(); +} + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +VOID +NTAPI +HalInitializeProcessor(IN ULONG ProcessorNumber, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + /* Set default stall count */ + KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT; + + /* Update the interrupt affinity and processor mask */ + InterlockedBitTestAndSet((PLONG)&HalpActiveProcessors, ProcessorNumber); + InterlockedBitTestAndSet((PLONG)&HalpDefaultInterruptAffinity, + ProcessorNumber); + + /* Register routines for KDCOM */ + //HalpRegisterKdSupportFunctions(); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalAllProcessorsStarted(VOID) +{ + /* Do nothing */ + return TRUE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalStartNextProcessor(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN PKPROCESSOR_STATE ProcessorState) +{ + /* Ready to start */ + return FALSE; +} + +/* + * @implemented + */ +VOID +NTAPI +HalProcessorIdle(VOID) +{ + /* Enable interrupts and halt the processor */ + _enable(); + __halt(); +} + +/* + * @implemented + */ +VOID +NTAPI +HalRequestIpi(KAFFINITY TargetProcessors) +{ + UNIMPLEMENTED; + __debugbreak(); +} + +/* EOF */ diff --git a/hal/halx86/amd64/stubs.c b/hal/halx86/amd64/stubs.c new file mode 100644 index 00000000000..ee295d17944 --- /dev/null +++ b/hal/halx86/amd64/stubs.c @@ -0,0 +1,97 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING.ARM in the top level directory + * FILE: hal/halx86/amd64/stubs.c + * PURPOSE: HAL stubs + * PROGRAMMERS: + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +LARGE_INTEGER HalpPerformanceFrequency; + + +/* FUNCTIONS ******************************************************************/ + +VOID +FASTCALL +HalClearSoftwareInterrupt( + IN KIRQL Irql) +{ + UNIMPLEMENTED; +} + +VOID +FASTCALL +HalRequestSoftwareInterrupt( + IN KIRQL Irql) +{ + UNIMPLEMENTED; +} + +BOOLEAN +NTAPI +HalBeginSystemInterrupt( + IN KIRQL Irql, + IN UCHAR Vector, + OUT PKIRQL OldIrql) +{ + UNIMPLEMENTED; + return FALSE; +} + +BOOLEAN +NTAPI +HalEnableSystemInterrupt( + IN UCHAR Vector, + IN KIRQL Irql, + IN KINTERRUPT_MODE InterruptMode) +{ + UNIMPLEMENTED; + return FALSE; +} + +VOID +NTAPI +HalDisableSystemInterrupt( + IN UCHAR Vector, + IN KIRQL Irql) +{ + UNIMPLEMENTED; +} + +VOID +NTAPI +HalEndSystemInterrupt( + IN KIRQL OldIrql, + IN PKTRAP_FRAME TrapFrame) +{ + UNIMPLEMENTED; +} + +LARGE_INTEGER +NTAPI +KeQueryPerformanceCounter( + OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL) +{ + LARGE_INTEGER Result; + +// ASSERT(HalpPerformanceFrequency.QuadPart != 0); + + /* Does the caller want the frequency? */ + if (PerformanceFrequency) + { + /* Return value */ + *PerformanceFrequency = HalpPerformanceFrequency; + } + + Result.QuadPart = __rdtsc(); + return Result; +} + diff --git a/hal/halx86/generic/amd64/systimer.S b/hal/halx86/amd64/systimer.S similarity index 100% rename from hal/halx86/generic/amd64/systimer.S rename to hal/halx86/amd64/systimer.S diff --git a/hal/halx86/generic/amd64/x86bios.c b/hal/halx86/amd64/x86bios.c similarity index 99% rename from hal/halx86/generic/amd64/x86bios.c rename to hal/halx86/amd64/x86bios.c index 3b43bf1d95f..a814873cbe0 100644 --- a/hal/halx86/generic/amd64/x86bios.c +++ b/hal/halx86/amd64/x86bios.c @@ -12,7 +12,7 @@ //#define NDEBUG #include -#include "x86emu.h" +//#include "x86emu.h" /* This page serves as fallback for pages used by Mm */ #define DEFAULT_PAGE 0x21 @@ -216,6 +216,7 @@ x86BiosWriteMemory( return STATUS_SUCCESS; } +#if 0 BOOLEAN NTAPI x86BiosCall( @@ -261,11 +262,13 @@ x86BiosCall( return TRUE; } +#endif BOOLEAN NTAPI HalpBiosDisplayReset(VOID) { +#if 0 X86_BIOS_REGISTERS Registers; ULONG OldEflags; @@ -283,7 +286,7 @@ HalpBiosDisplayReset(VOID) /* Restore previous flags */ __writeeflags(OldEflags); - +#endif return TRUE; } diff --git a/hal/halx86/generic/bus/halbus.c b/hal/halx86/generic/acpi/busemul.c similarity index 91% rename from hal/halx86/generic/bus/halbus.c rename to hal/halx86/generic/acpi/busemul.c index d8e478f450f..7a317f56728 100644 --- a/hal/halx86/generic/bus/halbus.c +++ b/hal/halx86/generic/acpi/busemul.c @@ -1,22 +1,20 @@ /* * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/halbus.c - * PURPOSE: Bus Support Routines - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: hal/halx86/generic/acpi/busemul.c + * PURPOSE: ACPI HAL Bus Handler Emulation Code + * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include #define NDEBUG #include -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ -ULONG HalpBusType; - -/* PRIVATE FUNCTIONS *********************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ VOID NTAPI @@ -83,11 +81,11 @@ HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, ULONG NTAPI -HalpGetSystemInterruptVector(IN ULONG BusNumber, - IN ULONG BusInterruptLevel, - IN ULONG BusInterruptVector, - OUT PKIRQL Irql, - OUT PKAFFINITY Affinity) +HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) { ULONG Vector = IRQ2VECTOR(BusInterruptLevel); *Irql = (KIRQL)VECTOR2IRQL(Vector); @@ -250,11 +248,11 @@ HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType, OUT PKAFFINITY Affinity) { /* Call the system bus translator */ - return HalpGetSystemInterruptVector(BusNumber, - BusInterruptLevel, - BusInterruptVector, - Irql, - Affinity); + return HalpGetSystemInterruptVector_Acpi(BusNumber, + BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity); } /* diff --git a/hal/halx86/generic/acpi/halacpi.c b/hal/halx86/generic/acpi/halacpi.c index 1efee7996a4..22d3c9b6a72 100644 --- a/hal/halx86/generic/acpi/halacpi.c +++ b/hal/halx86/generic/acpi/halacpi.c @@ -879,6 +879,24 @@ HalpInitializePciBus(VOID) HalpGetNMICrashFlag(); } +VOID +NTAPI +HalpInitNonBusHandler(VOID) +{ + /* These should be written by the PCI driver later, but we give defaults */ + HalPciTranslateBusAddress = HalpTranslateBusAddress; + HalPciAssignSlotResources = HalpAssignSlotResources; + HalFindBusAddressTranslation = HalpFindBusAddressTranslation; +} + +VOID +NTAPI +HalpInitBusHandlers(VOID) +{ + /* On ACPI, we only have a fake PCI bus to worry about */ + HalpInitNonBusHandler(); +} + VOID NTAPI HalpBuildAddressMap(VOID) diff --git a/hal/halx86/generic/bus/bushndlr.c b/hal/halx86/generic/bus/bushndlr.c deleted file mode 100644 index 18121360a62..00000000000 --- a/hal/halx86/generic/bus/bushndlr.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/bushndlr.c - * PURPOSE: Generic HAL Bus Handler Support - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) - */ - -/* INCLUDES *******************************************************************/ - -#include -#define NDEBUG -#include - -/* GLOBALS ********************************************************************/ - -KSPIN_LOCK HalpBusDatabaseSpinLock; -KEVENT HalpBusDatabaseEvent; -LIST_ENTRY HalpAllBusHandlers; -PARRAY HalpBusTable; -PARRAY HalpConfigTable; - -/* PRIVATE FUNCTIONS **********************************************************/ - -PARRAY -NTAPI -HalpAllocateArray(IN ULONG ArraySize) -{ - PARRAY Array; - ULONG Size; - - /* Compute array size */ - if (ArraySize == MAXULONG) ArraySize = 0; - Size = ArraySize * sizeof(PARRAY) + sizeof(ARRAY); - - /* Allocate the array */ - Array = ExAllocatePoolWithTag(NonPagedPool, - Size, - 'BusH'); - if (!Array) KeBugCheckEx(HAL_MEMORY_ALLOCATION, Size, 0, (ULONG_PTR)__FILE__, __LINE__); - - /* Initialize it */ - Array->ArraySize = ArraySize; - RtlZeroMemory(Array->Element, sizeof(PVOID) * (ArraySize + 1)); - return Array; -} - -VOID -NTAPI -HalpGrowArray(IN PARRAY *CurrentArray, - IN PARRAY *NewArray) -{ - PVOID Tmp; - - /* Check if the current array doesn't exist yet, or if it's smaller than the new one */ - if (!(*CurrentArray) || ((*NewArray)->ArraySize > (*CurrentArray)->ArraySize)) - { - /* Does it exist (and can it fit?) */ - if (*CurrentArray) - { - /* Copy the current array into the new one */ - RtlCopyMemory(&(*NewArray)->Element, - &(*CurrentArray)->Element, - sizeof(PVOID) * ((*CurrentArray)->ArraySize + 1)); - } - - /* Swap the pointers (XOR swap would be more l33t) */ - Tmp = *CurrentArray; - *CurrentArray = *NewArray; - *NewArray = Tmp; - } -} - -PBUS_HANDLER -FASTCALL -HalpLookupHandler(IN PARRAY Array, - IN ULONG Type, - IN ULONG Number, - IN BOOLEAN AddReference) -{ - PHAL_BUS_HANDLER Bus; - PBUS_HANDLER Handler = NULL; - - /* Make sure the entry exists */ - if (Array->ArraySize >= Type) - { - /* Retrieve it */ - Array = Array->Element[Type]; - - /* Make sure the entry array exists */ - if ((Array) && (Array->ArraySize >= Number)) - { - /* Retrieve the bus and its handler */ - Bus = Array->Element[Number]; - Handler = &Bus->Handler; - - /* Reference the handler if needed */ - if (AddReference) Bus->ReferenceCount++; - } - } - - /* Return the handler */ - return Handler; -} - -VOID -FASTCALL -HaliReferenceBusHandler(IN PBUS_HANDLER Handler) -{ - PHAL_BUS_HANDLER Bus; - - /* Find and reference the bus handler */ - Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); - Bus->ReferenceCount++; -} - -VOID -FASTCALL -HaliDereferenceBusHandler(IN PBUS_HANDLER Handler) -{ - PHAL_BUS_HANDLER Bus; - - /* Find and dereference the bus handler */ - Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); - Bus->ReferenceCount--; - ASSERT(Bus->ReferenceCount != 0); -} - -PBUS_HANDLER -FASTCALL -HaliHandlerForBus(IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber) -{ - /* Lookup the interface in the bus table */ - return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, FALSE); -} - -PBUS_HANDLER -FASTCALL -HaliHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, - IN ULONG BusNumber) -{ - /* Lookup the configuration in the configuration table */ - return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, FALSE); -} - -PBUS_HANDLER -FASTCALL -HaliReferenceHandlerForBus(IN INTERFACE_TYPE InterfaceType, - IN ULONG BusNumber) -{ - /* Lookup the interface in the bus table, and reference the handler */ - return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, TRUE); -} - -PBUS_HANDLER -FASTCALL -HaliReferenceHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, - IN ULONG BusNumber) -{ - /* Lookup the configuration in the configuration table and add a reference */ - return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, TRUE); -} - -VOID -NTAPI -HalpInitBusHandler(VOID) -{ - /* Setup the bus lock */ - KeInitializeSpinLock(&HalpBusDatabaseSpinLock); - - /* Setup the bus event */ - KeInitializeEvent(&HalpBusDatabaseEvent, SynchronizationEvent, TRUE); - - /* Setup the bus configuration and bus table */ - HalpBusTable = HalpAllocateArray(0); - HalpConfigTable = HalpAllocateArray(0); - - /* Setup the bus list */ - InitializeListHead(&HalpAllBusHandlers); - - /* These should be written by the PCI driver later, but we give defaults */ - HalPciTranslateBusAddress = HalpTranslateBusAddress; - HalPciAssignSlotResources = HalpAssignSlotResources; - HalFindBusAddressTranslation = HalpFindBusAddressTranslation; -} diff --git a/hal/halx86/generic/bus/isabus.c b/hal/halx86/generic/bus/isabus.c deleted file mode 100644 index 7e9631f6536..00000000000 --- a/hal/halx86/generic/bus/isabus.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/isabus.c - * PURPOSE: - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) - */ diff --git a/hal/halx86/generic/bus/sysbus.c b/hal/halx86/generic/bus/sysbus.c deleted file mode 100644 index d011cb568c5..00000000000 --- a/hal/halx86/generic/bus/sysbus.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * PROJECT: ReactOS HAL - * LICENSE: GPL - See COPYING in the top level directory - * FILE: hal/halx86/generic/bus/sysbus.c - * PURPOSE: - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) - */ diff --git a/hal/halx86/generic/halinit.c b/hal/halx86/generic/halinit.c index db54eb59d63..f0ebd33d4ca 100644 --- a/hal/halx86/generic/halinit.c +++ b/hal/halx86/generic/halinit.c @@ -14,223 +14,10 @@ /* GLOBALS *******************************************************************/ -/* Share with Mm headers? */ -#define MM_HAL_VA_START (PVOID)0xFFC00000 -#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024)) - BOOLEAN HalpPciLockSettings; -ULONG HalpUsedAllocDescriptors; -MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64]; -PVOID HalpHeapStart = MM_HAL_HEAP_START; /* PRIVATE FUNCTIONS *********************************************************/ -ULONG -NTAPI -HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, - IN ULONG MaxAddress, - IN ULONG PageCount, - IN BOOLEAN Aligned) -{ - ULONG UsedDescriptors, Alignment, PhysicalAddress; - PFN_NUMBER MaxPage, BasePage; - PLIST_ENTRY NextEntry; - PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock; - - /* Highest page we'll go */ - MaxPage = MaxAddress >> PAGE_SHIFT; - - /* We need at least two blocks */ - if ((HalpUsedAllocDescriptors + 2) > 64) return 0; - - /* Remember how many we have now */ - UsedDescriptors = HalpUsedAllocDescriptors; - - /* Loop the loader block memory descriptors */ - NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) - { - /* Get the block */ - MdBlock = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* No alignment by default */ - Alignment = 0; - - /* Unless requested, in which case we use a 64KB block alignment */ - if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage; - - /* Search for free memory */ - if ((MdBlock->MemoryType == LoaderFree) || - (MdBlock->MemoryType == MemoryFirmwareTemporary)) - { - /* Make sure the page is within bounds, including alignment */ - BasePage = MdBlock->BasePage; - if ((BasePage) && - (MdBlock->PageCount >= PageCount + Alignment) && - (BasePage + PageCount + Alignment < MaxPage)) - { - - /* We found an address */ - PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT; - break; - } - } - - /* Keep trying */ - NextEntry = NextEntry->Flink; - } - - /* If we didn't find anything, get out of here */ - if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0; - - /* Okay, now get a descriptor */ - NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors]; - NewBlock->PageCount = PageCount; - NewBlock->BasePage = MdBlock->BasePage + Alignment; - NewBlock->MemoryType = LoaderHALCachedMemory; - - /* Update count */ - UsedDescriptors++; - HalpUsedAllocDescriptors = UsedDescriptors; - - /* Check if we had any alignment */ - if (Alignment) - { - /* Check if we had leftovers */ - if ((MdBlock->PageCount - Alignment) != PageCount) - { - /* Get the next descriptor */ - FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors]; - FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount; - FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount; - - /* One more */ - HalpUsedAllocDescriptors++; - - /* Insert it into the list */ - InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry); - } - - /* Use this descriptor */ - NewBlock->PageCount = Alignment; - InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry); - } - else - { - /* Consume memory from this block */ - MdBlock->BasePage += PageCount; - MdBlock->PageCount -= PageCount; - - /* Insert the descriptor */ - InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry); - - /* Remove the entry if the whole block was allocated */ - if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry); - } - - /* Return the address */ - return PhysicalAddress; -} - -PVOID -NTAPI -HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG PageCount) -{ - PHARDWARE_PTE PointerPte; - ULONG UsedPages = 0; - PVOID VirtualAddress, BaseAddress; - - /* Start at the current HAL heap base */ - BaseAddress = HalpHeapStart; - VirtualAddress = BaseAddress; - - /* Loop until we have all the pages required */ - while (UsedPages < PageCount) - { - /* If this overflows past the HAL heap, it means there's no space */ - if (VirtualAddress == NULL) return NULL; - - /* Get the PTE for this address */ - PointerPte = HalAddressToPte(VirtualAddress); - - /* Go to the next page */ - VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); - - /* Check if the page is available */ - if (PointerPte->Valid) - { - /* PTE has data, skip it and start with a new base address */ - BaseAddress = VirtualAddress; - UsedPages = 0; - continue; - } - - /* PTE is available, keep going on this run */ - UsedPages++; - } - - /* Take the base address of the page plus the actual offset in the address */ - VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress + - BYTE_OFFSET(PhysicalAddress.LowPart)); - - /* If we are starting at the heap, move the heap */ - if (BaseAddress == HalpHeapStart) - { - /* Past this allocation */ - HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE)); - } - - /* Loop pages that can be mapped */ - while (UsedPages--) - { - /* Fill out the PTE */ - PointerPte = HalAddressToPte(BaseAddress); - PointerPte->PageFrameNumber = PhysicalAddress.QuadPart >> PAGE_SHIFT; - PointerPte->Valid = 1; - PointerPte->Write = 1; - - /* Move to the next address */ - PhysicalAddress.QuadPart += PAGE_SIZE; - BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE); - } - - /* Flush the TLB and return the address */ - HalpFlushTLB(); - return VirtualAddress; -} - -VOID -NTAPI -HalpUnmapVirtualAddress(IN PVOID VirtualAddress, - IN ULONG PageCount) -{ - PHARDWARE_PTE PointerPte; - ULONG i; - - /* Only accept valid addresses */ - if (VirtualAddress < MM_HAL_VA_START) return; - - /* Align it down to page size */ - VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1)); - - /* Loop PTEs */ - PointerPte = HalAddressToPte(VirtualAddress); - for (i = 0; i < PageCount; i++) - { - *(PULONG)PointerPte = 0; - PointerPte++; - } - - /* Flush the TLB */ - HalpFlushTLB(); - - /* Put the heap back */ - if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress; -} - VOID NTAPI HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock) @@ -368,7 +155,7 @@ HalInitSystem(IN ULONG BootPhase, else if (BootPhase == 1) { /* Initialize bus handlers */ - HalpInitBusHandler(); + HalpInitBusHandlers(); #ifndef _MINIHAL_ /* Enable IRQ 0 */ diff --git a/hal/halx86/generic/legacy/bus/bushndlr.c b/hal/halx86/generic/legacy/bus/bushndlr.c new file mode 100644 index 00000000000..7cb3a205cea --- /dev/null +++ b/hal/halx86/generic/legacy/bus/bushndlr.c @@ -0,0 +1,421 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/bushndlr.c + * PURPOSE: Generic HAL Bus Handler Support + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +KSPIN_LOCK HalpBusDatabaseSpinLock; +KEVENT HalpBusDatabaseEvent; +LIST_ENTRY HalpAllBusHandlers; +PARRAY HalpBusTable; +PARRAY HalpConfigTable; + +/* PRIVATE FUNCTIONS **********************************************************/ + +PARRAY +NTAPI +HalpAllocateArray(IN ULONG ArraySize) +{ + PARRAY Array; + ULONG Size; + + /* Compute array size */ + if (ArraySize == MAXULONG) ArraySize = 0; + Size = ArraySize * sizeof(PARRAY) + sizeof(ARRAY); + + /* Allocate the array */ + Array = ExAllocatePoolWithTag(NonPagedPool, + Size, + 'BusH'); + if (!Array) KeBugCheckEx(HAL_MEMORY_ALLOCATION, Size, 0, (ULONG_PTR)__FILE__, __LINE__); + + /* Initialize it */ + Array->ArraySize = ArraySize; + RtlZeroMemory(Array->Element, sizeof(PVOID) * (ArraySize + 1)); + return Array; +} + +VOID +NTAPI +HalpGrowArray(IN PARRAY *CurrentArray, + IN PARRAY *NewArray) +{ + PVOID Tmp; + + /* Check if the current array doesn't exist yet, or if it's smaller than the new one */ + if (!(*CurrentArray) || ((*NewArray)->ArraySize > (*CurrentArray)->ArraySize)) + { + /* Does it exist (and can it fit?) */ + if (*CurrentArray) + { + /* Copy the current array into the new one */ + RtlCopyMemory(&(*NewArray)->Element, + &(*CurrentArray)->Element, + sizeof(PVOID) * ((*CurrentArray)->ArraySize + 1)); + } + + /* Swap the pointers (XOR swap would be more l33t) */ + Tmp = *CurrentArray; + *CurrentArray = *NewArray; + *NewArray = Tmp; + } +} + +PBUS_HANDLER +FASTCALL +HalpLookupHandler(IN PARRAY Array, + IN ULONG Type, + IN ULONG Number, + IN BOOLEAN AddReference) +{ + PHAL_BUS_HANDLER Bus; + PBUS_HANDLER Handler = NULL; + + /* Make sure the entry exists */ + if (Array->ArraySize >= Type) + { + /* Retrieve it */ + Array = Array->Element[Type]; + + /* Make sure the entry array exists */ + if ((Array) && (Array->ArraySize >= Number)) + { + /* Retrieve the bus and its handler */ + Bus = Array->Element[Number]; + Handler = &Bus->Handler; + + /* Reference the handler if needed */ + if (AddReference) Bus->ReferenceCount++; + } + } + + /* Return the handler */ + return Handler; +} + +ULONG +NTAPI +HalpNoBusData(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + /* Not implemented */ + DPRINT1("STUB GetSetBusData\n"); + return 0; +} + +NTSTATUS +NTAPI +HalpNoAdjustResourceList(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList) +{ + DPRINT1("STUB Adjustment\n"); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +HalpNoAssignSlotResources(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName OPTIONAL, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject OPTIONAL, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + DPRINT1("STUB Assignment\n"); + return STATUS_NOT_SUPPORTED; +} + +VOID +FASTCALL +HaliReferenceBusHandler(IN PBUS_HANDLER Handler) +{ + PHAL_BUS_HANDLER Bus; + + /* Find and reference the bus handler */ + Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); + Bus->ReferenceCount++; +} + +VOID +FASTCALL +HaliDereferenceBusHandler(IN PBUS_HANDLER Handler) +{ + PHAL_BUS_HANDLER Bus; + + /* Find and dereference the bus handler */ + Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); + Bus->ReferenceCount--; + ASSERT(Bus->ReferenceCount != 0); +} + +PBUS_HANDLER +FASTCALL +HaliHandlerForBus(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber) +{ + /* Lookup the interface in the bus table */ + return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, FALSE); +} + +PBUS_HANDLER +FASTCALL +HaliHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, + IN ULONG BusNumber) +{ + /* Lookup the configuration in the configuration table */ + return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, FALSE); +} + +PBUS_HANDLER +FASTCALL +HaliReferenceHandlerForBus(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber) +{ + /* Lookup the interface in the bus table, and reference the handler */ + return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, TRUE); +} + +PBUS_HANDLER +FASTCALL +HaliReferenceHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, + IN ULONG BusNumber) +{ + /* Lookup the configuration in the configuration table and add a reference */ + return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, TRUE); +} + +#ifndef _MINIHAL_ +NTSTATUS +NTAPI +HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, + IN BUS_DATA_TYPE ConfigType, + IN ULONG BusNumber, + IN INTERFACE_TYPE ParentBusType, + IN ULONG ParentBusNumber, + IN ULONG ExtraData, + IN PINSTALL_BUS_HANDLER InstallCallback, + OUT PBUS_HANDLER *ReturnedBusHandler) +{ + PHAL_BUS_HANDLER Bus, OldHandler = NULL; + PHAL_BUS_HANDLER* BusEntry; + //PVOID CodeHandle; + PARRAY InterfaceArray, InterfaceBusNumberArray, ConfigArray, ConfigBusNumberArray; + PBUS_HANDLER ParentHandler; + KIRQL OldIrql; + NTSTATUS Status; + + /* Make sure we have a valid handler */ + ASSERT((InterfaceType != InterfaceTypeUndefined) || + (ConfigType != ConfigurationSpaceUndefined)); + + /* Allocate the bus handler */ + Bus = ExAllocatePoolWithTag(NonPagedPool, + sizeof(HAL_BUS_HANDLER) + ExtraData, + 'HsuB'); + if (!Bus) return STATUS_INSUFFICIENT_RESOURCES; + + /* Return the handler */ + *ReturnedBusHandler = &Bus->Handler; + + /* FIXME: Fix the kernel first. Don't page us out */ + //CodeHandle = MmLockPagableDataSection(&HaliRegisterBusHandler); + + /* Synchronize with anyone else */ + KeWaitForSingleObject(&HalpBusDatabaseEvent, + WrExecutive, + KernelMode, + FALSE, + NULL); + + /* Check for unknown/root bus */ + if (BusNumber == -1) + { + /* We must have an interface */ + ASSERT(InterfaceType != InterfaceTypeUndefined); + + /* Find the right bus */ + BusNumber = 0; + while (HaliHandlerForBus(InterfaceType, BusNumber)) BusNumber++; + } + + /* Allocate arrays for the handler */ + InterfaceArray = HalpAllocateArray(InterfaceType); + InterfaceBusNumberArray = HalpAllocateArray(BusNumber); + ConfigArray = HalpAllocateArray(ConfigType); + ConfigBusNumberArray = HalpAllocateArray(BusNumber); + + /* Only proceed if all allocations succeeded */ + if (InterfaceArray && InterfaceBusNumberArray && ConfigArray && ConfigBusNumberArray) + { + /* Find the parent handler if any */ + ParentHandler = HaliReferenceHandlerForBus(ParentBusType, ParentBusNumber); + + /* Initialize the handler */ + RtlZeroMemory(Bus, sizeof(HAL_BUS_HANDLER) + ExtraData); + Bus->ReferenceCount = 1; + + /* Fill out bus data */ + Bus->Handler.BusNumber = BusNumber; + Bus->Handler.InterfaceType = InterfaceType; + Bus->Handler.ConfigurationType = ConfigType; + Bus->Handler.ParentHandler = ParentHandler; + + /* Fill out dummy handlers */ + Bus->Handler.GetBusData = HalpNoBusData; + Bus->Handler.SetBusData = HalpNoBusData; + Bus->Handler.AdjustResourceList = HalpNoAdjustResourceList; + Bus->Handler.AssignSlotResources = HalpNoAssignSlotResources; + + /* Make space for extra data */ + if (ExtraData) Bus->Handler.BusData = Bus + 1; + + /* Check for a parent handler */ + if (ParentHandler) + { + /* Inherit the parent routines */ + Bus->Handler.GetBusData = ParentHandler->GetBusData; + Bus->Handler.SetBusData = ParentHandler->SetBusData; + Bus->Handler.AdjustResourceList = ParentHandler->AdjustResourceList; + Bus->Handler.AssignSlotResources = ParentHandler->AssignSlotResources; + Bus->Handler.TranslateBusAddress = ParentHandler->TranslateBusAddress; + Bus->Handler.GetInterruptVector = ParentHandler->GetInterruptVector; + } + + /* We don't support this yet */ + ASSERT(!InstallCallback); + + /* Lock the buses */ + KeAcquireSpinLock(&HalpBusDatabaseSpinLock, &OldIrql); + + /* Make space for the interface */ + HalpGrowArray(&HalpBusTable, &InterfaceArray); + + /* Check if we really have an interface */ + if (InterfaceType != InterfaceTypeUndefined) + { + /* Make space for the association */ + HalpGrowArray((PARRAY*)&HalpBusTable->Element[InterfaceType], + &InterfaceBusNumberArray); + + /* Get the bus handler pointer */ + BusEntry = (PHAL_BUS_HANDLER*)&((PARRAY)HalpBusTable->Element[InterfaceType])->Element[BusNumber]; + + /* Check if there was already a handler there, and set the new one */ + if (*BusEntry) OldHandler = *BusEntry; + *BusEntry = Bus; + } + + /* Now add a space for the configuration space */ + HalpGrowArray(&HalpConfigTable, &ConfigArray); + + /* Check if we really have one */ + if (ConfigType != ConfigurationSpaceUndefined) + { + /* Make space for this association */ + HalpGrowArray((PARRAY*)&HalpConfigTable->Element[ConfigType], + &ConfigBusNumberArray); + + /* Get the bus handler pointer */ + BusEntry = (PHAL_BUS_HANDLER*)&((PARRAY)HalpConfigTable->Element[ConfigType])->Element[BusNumber]; + if (*BusEntry) + { + /* Get the old entry, but make sure it's the same we had before */ + ASSERT((OldHandler == NULL) || (OldHandler == *BusEntry)); + OldHandler = *BusEntry; + } + + /* Set the new entry */ + *BusEntry = Bus; + } + + /* Link the adapter */ + InsertTailList(&HalpAllBusHandlers, &Bus->AllHandlers); + + /* Remove the old linkage */ + Bus = OldHandler; + if (Bus) RemoveEntryList(&Bus->AllHandlers); + + /* Release the lock */ + KeReleaseSpinLock(&HalpBusDatabaseSpinLock, OldIrql); + Status = STATUS_SUCCESS; + } + else + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + + /* Signal the event */ + KeSetEvent(&HalpBusDatabaseEvent, 0, FALSE); + + /* FIXME: Fix the kernel first. Re-page the function */ + //MmUnlockPagableImageSection(CodeHandle); + + /* Free all allocations */ + if (Bus) ExFreePool(Bus); + if (InterfaceArray) ExFreePool(InterfaceArray); + if (InterfaceBusNumberArray) ExFreePool(InterfaceBusNumberArray); + if (ConfigArray) ExFreePool(ConfigArray); + if (ConfigBusNumberArray) ExFreePool(ConfigBusNumberArray); + + /* And we're done */ + return Status; +} +#endif + +VOID +NTAPI +HalpInitBusHandler(VOID) +{ + /* Setup the bus lock */ + KeInitializeSpinLock(&HalpBusDatabaseSpinLock); + + /* Setup the bus event */ + KeInitializeEvent(&HalpBusDatabaseEvent, SynchronizationEvent, TRUE); + + /* Setup the bus configuration and bus table */ + HalpBusTable = HalpAllocateArray(0); + HalpConfigTable = HalpAllocateArray(0); + + /* Setup the bus list */ + InitializeListHead(&HalpAllBusHandlers); + + /* Setup the HAL Dispatch routines */ +#ifndef _MINIHAL_ + HalRegisterBusHandler = HaliRegisterBusHandler; + HalHandlerForBus = HaliHandlerForBus; + HalHandlerForConfigSpace = HaliHandlerForConfigSpace; + HalReferenceHandlerForBus = HaliReferenceHandlerForBus; + HalReferenceBusHandler = HaliReferenceBusHandler; + HalDereferenceBusHandler = HaliDereferenceBusHandler; +#endif + HalPciAssignSlotResources = HalpAssignSlotResources; + /* FIXME: Fix later */ +#if 0 + HalPciTranslateBusAddress = HaliTranslateBusAddress; + if (!HalFindBusAddressTranslation) HalFindBusAddressTranslation = HaliFindBusAddressTranslation; +#else + /* These should be written by the PCI driver later, but we give defaults */ + HalPciTranslateBusAddress = HalpTranslateBusAddress; + HalFindBusAddressTranslation = HalpFindBusAddressTranslation; +#endif +} + +/* EOF */ diff --git a/hal/halx86/generic/legacy/bus/cmosbus.c b/hal/halx86/generic/legacy/bus/cmosbus.c new file mode 100644 index 00000000000..279aebf9e20 --- /dev/null +++ b/hal/halx86/generic/legacy/bus/cmosbus.c @@ -0,0 +1,47 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/sysbus.c + * PURPOSE: + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +ULONG +NTAPI +HalpcGetCmosData(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + DPRINT1("CMOS GetData\n"); + while (TRUE); + return 0; +} + +ULONG +NTAPI +HalpcSetCmosData(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + DPRINT1("CMOS SetData\n"); + while (TRUE); + return 0; +} + +/* EOF */ diff --git a/hal/halx86/generic/legacy/bus/isabus.c b/hal/halx86/generic/legacy/bus/isabus.c new file mode 100644 index 00000000000..884e6d026bb --- /dev/null +++ b/hal/halx86/generic/legacy/bus/isabus.c @@ -0,0 +1,32 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/isabus.c + * PURPOSE: + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOLEAN +NTAPI +HalpTranslateIsaBusAddress(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + DPRINT1("ISA Translate\n"); + while (TRUE); + return FALSE; +} + +/* EOF */ diff --git a/hal/halx86/generic/bus/pcibus.c b/hal/halx86/generic/legacy/bus/pcibus.c similarity index 95% rename from hal/halx86/generic/bus/pcibus.c rename to hal/halx86/generic/legacy/bus/pcibus.c index 3c46e805122..fe49b731fcb 100644 --- a/hal/halx86/generic/bus/pcibus.c +++ b/hal/halx86/generic/legacy/bus/pcibus.c @@ -14,6 +14,8 @@ /* GLOBALS *******************************************************************/ +ULONG HalpBusType; + PCI_TYPE1_CFG_CYCLE_BITS HalpPciDebuggingDevice[2] = {{{{0}}}}; BOOLEAN HalpPCIConfigInitialized; @@ -391,7 +393,6 @@ HalpGetPCIData(IN PBUS_HANDLER BusHandler, if (PciConfig->VendorID == PCI_INVALID_VENDORID) { /* It's invalid, but we want to return this much */ - PciConfig->VendorID = PCI_INVALID_VENDORID; Len = sizeof(USHORT); } @@ -506,6 +507,55 @@ HalpSetPCIData(IN PBUS_HANDLER BusHandler, return Len; } +ULONG +NTAPI +HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + UNIMPLEMENTED; + while (TRUE); + return 0; +} + +VOID +NTAPI +HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData) +{ + UNIMPLEMENTED; + while (TRUE); +} + +VOID +NTAPI +HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData) +{ + UNIMPLEMENTED; + while (TRUE); +} + +NTSTATUS +NTAPI +HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER PciSlot, + OUT PSUPPORTED_RANGE *Range) +{ + UNIMPLEMENTED; + while (TRUE); + return STATUS_SUCCESS; +} + NTSTATUS NTAPI HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock, @@ -559,6 +609,18 @@ PciSize(ULONG Base, ULONG Mask) return Size; } +NTSTATUS +NTAPI +HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList) +{ + /* Not yet supported */ + DbgPrint("HAL: PCI Resource List Adjustment not implemented!"); + while (TRUE); + return STATUS_UNSUCCESSFUL; +} + NTSTATUS NTAPI HalpAssignPCISlotResources(IN PBUS_HANDLER BusHandler, @@ -1062,3 +1124,5 @@ HalpInitializePciStubs(VOID) HalpPCIConfigInitialized = TRUE; } +/* EOF */ + diff --git a/hal/halx86/generic/bus/pcidata.c b/hal/halx86/generic/legacy/bus/pcidata.c similarity index 100% rename from hal/halx86/generic/bus/pcidata.c rename to hal/halx86/generic/legacy/bus/pcidata.c diff --git a/hal/halx86/generic/legacy/bus/sysbus.c b/hal/halx86/generic/legacy/bus/sysbus.c new file mode 100644 index 00000000000..ab8d2925c44 --- /dev/null +++ b/hal/halx86/generic/legacy/bus/sysbus.c @@ -0,0 +1,47 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/bus/sysbus.c + * PURPOSE: + * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOLEAN +NTAPI +HalpTranslateSystemBusAddress(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + DPRINT1("SYSTEM Translate\n"); + while (TRUE); + return FALSE; +} + +ULONG +NTAPI +HalpGetSystemInterruptVector(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + /* Get the root vector */ + DPRINT1("SYSTEM GetVector\n"); + while (TRUE); + return 0; +} + +/* EOF */ diff --git a/hal/halx86/generic/legacy/bussupp.c b/hal/halx86/generic/legacy/bussupp.c new file mode 100644 index 00000000000..8d8f799c541 --- /dev/null +++ b/hal/halx86/generic/legacy/bussupp.c @@ -0,0 +1,963 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: hal/halx86/generic/legacy/bussupp.c + * PURPOSE: HAL Legacy Bus Support Code + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +extern KSPIN_LOCK HalpPCIConfigLock; +ULONG HalpPciIrqMask; + +/* PRIVATE FUNCTIONS **********************************************************/ + +PBUS_HANDLER +NTAPI +HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType, + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN INTERFACE_TYPE ParentBusInterfaceType, + IN ULONG ParentBusNumber, + IN ULONG BusSpecificData) +{ + PBUS_HANDLER Bus; + + /* Register the bus handler */ + HalRegisterBusHandler(InterfaceType, + BusDataType, + BusNumber, + ParentBusInterfaceType, + ParentBusNumber, + BusSpecificData, + NULL, + &Bus); + if (!Bus) return NULL; + + /* Check for a valid interface */ + if (InterfaceType != InterfaceTypeUndefined) + { + /* Allocate address ranges and zero them out */ + Bus->BusAddresses = ExAllocatePoolWithTag(NonPagedPool, + sizeof(SUPPORTED_RANGES), + ' laH'); + RtlZeroMemory(Bus->BusAddresses, sizeof(SUPPORTED_RANGES)); + + /* Build the data structure */ + Bus->BusAddresses->Version = HAL_SUPPORTED_RANGE_VERSION; + Bus->BusAddresses->Dma.Limit = 7; + Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF; + Bus->BusAddresses->IO.Limit = 0xFFFF; + Bus->BusAddresses->IO.SystemAddressSpace = 1; + Bus->BusAddresses->PrefetchMemory.Base = 1; + } + + /* Return the bus address */ + return Bus; +} + +VOID +NTAPI +HalpRegisterInternalBusHandlers(VOID) +{ + PBUS_HANDLER Bus; + + /* Only do processor 1 */ + if (KeGetCurrentPrcb()->Number) return; + + /* Register root support */ + HalpInitBusHandler(); + + /* Allocate the system bus */ + Bus = HalpAllocateBusHandler(Internal, + ConfigurationSpaceUndefined, + 0, + InterfaceTypeUndefined, + 0, + 0); + DPRINT1("Registering Internal Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetInterruptVector = HalpGetSystemInterruptVector; + Bus->TranslateBusAddress = HalpTranslateSystemBusAddress; + } + + /* Allocate the CMOS bus */ + Bus = HalpAllocateBusHandler(InterfaceTypeUndefined, + Cmos, + 0, + InterfaceTypeUndefined, + 0, + 0); + DPRINT1("Registering CMOS Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetBusData = HalpcGetCmosData; + Bus->SetBusData = HalpcSetCmosData; + } + + /* Allocate the CMOS bus */ + Bus = HalpAllocateBusHandler(InterfaceTypeUndefined, + Cmos, + 1, + InterfaceTypeUndefined, + 0, + 0); + DPRINT1("Registering CMOS Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetBusData = HalpcGetCmosData; + Bus->SetBusData = HalpcSetCmosData; + } + + /* Allocate ISA bus */ + Bus = HalpAllocateBusHandler(Isa, + ConfigurationSpaceUndefined, + 0, + Internal, + 0, + 0); + DPRINT1("Registering ISA Bus: %p\n", Bus); + if (Bus) + { + /* Set it up */ + Bus->GetBusData = HalpNoBusData; + Bus->BusAddresses->Memory.Limit = 0xFFFFFF; + Bus->TranslateBusAddress = HalpTranslateIsaBusAddress; + } + + /* No support for EISA or MCA */ + ASSERT(HalpBusType == MACHINE_TYPE_ISA); +} + +#ifndef _MINIHAL_ +NTSTATUS +NTAPI +HalpMarkChipsetDecode(BOOLEAN OverrideEnable) +{ + NTSTATUS Status; + UNICODE_STRING KeyString; + ULONG Data = OverrideEnable; + HANDLE KeyHandle, Handle; + + /* Open CCS key */ + RtlInitUnicodeString(&KeyString, + L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"); + Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE); + if (NT_SUCCESS(Status)) + { + /* Open PNP Bios key */ + RtlInitUnicodeString(&KeyString, L"Control\\Biosinfo\\PNPBios"); + Status = HalpOpenRegistryKey(&KeyHandle, + Handle, + &KeyString, + KEY_ALL_ACCESS, + TRUE); + + /* Close root key */ + ZwClose(Handle); + + /* Check if PNP BIOS key exists */ + if (NT_SUCCESS(Status)) + { + /* Set the override value */ + RtlInitUnicodeString(&KeyString, L"FullDecodeChipsetOverride"); + Status = ZwSetValueKey(KeyHandle, + &KeyString, + 0, + REG_DWORD, + &Data, + sizeof(Data)); + + /* Close subkey */ + ZwClose(KeyHandle); + } + } + + /* Return status */ + return Status; +} + +PBUS_HANDLER +NTAPI +HalpAllocateAndInitPciBusHandler(IN ULONG PciType, + IN ULONG BusNo, + IN BOOLEAN TestAllocation) +{ + PBUS_HANDLER Bus; + PPCIPBUSDATA BusData; + + /* Allocate the bus handler */ + Bus = HalpAllocateBusHandler(PCIBus, + PCIConfiguration, + BusNo, + Internal, + 0, + sizeof(PCIPBUSDATA)); + + /* Set it up */ + Bus->GetBusData = (PGETSETBUSDATA)HalpGetPCIData; + Bus->SetBusData = (PGETSETBUSDATA)HalpSetPCIData; + Bus->GetInterruptVector = (PGETINTERRUPTVECTOR)HalpGetPCIIntOnISABus; + Bus->AdjustResourceList = (PADJUSTRESOURCELIST)HalpAdjustPCIResourceList; + Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES)HalpAssignPCISlotResources; + Bus->BusAddresses->Dma.Limit = 0; + + /* Get our custom bus data */ + BusData = (PPCIPBUSDATA)Bus->BusData; + + /* Setup custom bus data */ + BusData->CommonData.Tag = PCI_DATA_TAG; + BusData->CommonData.Version = PCI_DATA_VERSION; + BusData->CommonData.ReadConfig = (PciReadWriteConfig)HalpReadPCIConfig; + BusData->CommonData.WriteConfig = (PciReadWriteConfig)HalpWritePCIConfig; + BusData->CommonData.Pin2Line = (PciPin2Line)HalpPCIPin2ISALine; + BusData->CommonData.Line2Pin = (PciLine2Pin)HalpPCIISALine2Pin; + BusData->MaxDevice = PCI_MAX_DEVICES; + BusData->GetIrqRange = (PciIrqRange)HalpGetISAFixedPCIIrq; + + /* Initialize the bitmap */ + RtlInitializeBitMap(&BusData->DeviceConfigured, BusData->ConfiguredBits, 256); + + /* Check the type of PCI bus */ + switch (PciType) + { + /* Type 1 PCI Bus */ + case 1: + + /* Copy the Type 1 handler data */ + RtlCopyMemory(&PCIConfigHandler, + &PCIConfigHandlerType1, + sizeof(PCIConfigHandler)); + + /* Set correct I/O Ports */ + BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT; + BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT; + break; + + /* Type 2 PCI Bus */ + case 2: + + /* Copy the Type 1 handler data */ + RtlCopyMemory(&PCIConfigHandler, + &PCIConfigHandlerType2, + sizeof (PCIConfigHandler)); + + /* Set correct I/O Ports */ + BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT; + BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT; + BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE; + + /* Only 16 devices supported, not 32 */ + BusData->MaxDevice = 16; + break; + + default: + + /* Invalid type */ + DbgPrint("HAL: Unnkown PCI type\n"); + } + + /* Return the bus handler */ + return Bus; +} + +BOOLEAN +NTAPI +HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler, + IN PCI_SLOT_NUMBER Slot) +{ + UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; + PPCI_COMMON_CONFIG PciHeader = (PVOID)DataBuffer; + ULONG i; + ULONG_PTR Address; + + /* Read the PCI header */ + HalpReadPCIConfig(BusHandler, Slot, PciHeader, 0, PCI_COMMON_HDR_LENGTH); + + /* Make sure it's a valid device */ + if ((PciHeader->VendorID == PCI_INVALID_VENDORID) || + (PCI_CONFIGURATION_TYPE(PciHeader) != PCI_DEVICE_TYPE)) + { + /* Bail out */ + return FALSE; + } + + /* Make sure interrupt numbers make sense */ + if (((PciHeader->u.type0.InterruptPin) && + (PciHeader->u.type0.InterruptPin > 4)) || + (PciHeader->u.type0.InterruptLine & 0x70)) + { + /* Bail out */ + return FALSE; + } + + /* Now scan PCI BARs */ + for (i = 0; i < PCI_TYPE0_ADDRESSES; i++) + { + /* Check what kind of address it is */ + Address = PciHeader->u.type0.BaseAddresses[i]; + if (Address & PCI_ADDRESS_IO_SPACE) + { + /* Highest I/O port is 65535 */ + if (Address > 0xFFFF) return FALSE; + } + else + { + /* MMIO should be higher than 0x80000 */ + if ((Address > 0xF) && (Address < 0x80000)) return FALSE; + } + + /* Is this a 64-bit address? */ + if (!(Address & PCI_ADDRESS_IO_SPACE) && + ((Address & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)) + { + /* Check the next-next entry, since this one 64-bits wide */ + i++; + } + } + + /* Header, interrupt and address data all make sense */ + return TRUE; +} + +static BOOLEAN WarningsGiven[5]; + +NTSTATUS +NTAPI +HalpGetChipHacks(IN USHORT VendorId, + IN USHORT DeviceId, + IN UCHAR RevisionId, + IN PULONG HackFlags) +{ + /* Not yet implemented */ + if (!WarningsGiven[0]++) DbgPrint("HAL: Not checking for PCI Chipset Hacks. Your hardware may malfunction!\n"); + *HackFlags = 0; + return STATUS_UNSUCCESSFUL; +} + +BOOLEAN +NTAPI +HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo, + IN PPCI_COMMON_CONFIG PciData, + IN ULONG Flags) +{ + /* Not yet implemented */ + if (!WarningsGiven[1]++) DbgPrint("HAL: Not checking for PCI Cards with Extended Addressing. Your hardware may malfunction!\n"); + return FALSE; +} + +BOOLEAN +NTAPI +HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData) +{ + /* Not yet implemented */ + if (!WarningsGiven[2]++) DbgPrint("HAL: Not checking for PCI Cards that are IDE devices. Your hardware may malfunction!\n"); + return FALSE; +} + +BOOLEAN +NTAPI +HalpGetPciBridgeConfig(IN ULONG PciType, + IN PUCHAR MaxPciBus) +{ + /* Not yet implemented */ + if (!WarningsGiven[3]++) DbgPrint("HAL: Not checking for PCI-to-PCI Bridges. Your hardware may malfunction!\n"); + return FALSE; +} + +VOID +NTAPI +HalpFixupPciSupportedRanges(IN ULONG MaxBuses) +{ + /* Not yet implemented */ + if (!WarningsGiven[4]++) DbgPrint("HAL: Not adjusting Bridge-to-Child PCI Address Ranges. Your hardware may malfunction!\n"); +} +#endif + +VOID +NTAPI +HalpInitializePciBus(VOID) +{ +#ifndef _MINIHAL_ + PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo; + UCHAR PciType; + PCI_SLOT_NUMBER PciSlot; + ULONG i, j, k; + UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; + PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer; + PBUS_HANDLER BusHandler; + ULONG HackFlags; + BOOLEAN ExtendedAddressDecoding = FALSE; + + /* Query registry information */ + PciRegistryInfo = HalpQueryPciRegistryInfo(); + if (!PciRegistryInfo) return; + + /* Initialize the PCI configuration lock */ + KeInitializeSpinLock(&HalpPCIConfigLock); + + /* Get the type and free the info structure */ + PciType = PciRegistryInfo->HardwareMechanism & 0xF; + + /* Check if this is a type 2 PCI bus with at least one bus */ + if ((PciRegistryInfo->NoBuses) && (PciType == 2)) + { + /* Setup the PCI slot */ + PciSlot.u.bits.Reserved = 0; + PciSlot.u.bits.FunctionNumber = 0; + + /* Loop all slots */ + for (i = 0; i < 32; i++) + { + /* Try to setup a Type 2 PCI slot */ + PciType = 2; + BusHandler = HalpAllocateAndInitPciBusHandler(2, 0, TRUE); + if (!BusHandler) break; + + /* Now check if it's valid */ + if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break; + + /* Heh, the BIOS lied... try Type 1 */ + PciType = 1; + BusHandler = HalpAllocateAndInitPciBusHandler(1, 0, TRUE); + if (!BusHandler) break; + + /* Now check if it's valid */ + if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break; + + /* Keep trying */ + PciType = 2; + } + + /* Now allocate the correct kind of handler */ + HalpAllocateAndInitPciBusHandler(PciType, 0, FALSE); + } + + /* Okay, now loop all PCI bridges */ + do + { + /* Loop all PCI buses */ + for (i = 0; i < PciRegistryInfo->NoBuses; i++) + { + /* Check if we have a handler for it */ + if (!HalHandlerForBus(PCIBus, i)) + { + /* Allocate it */ + HalpAllocateAndInitPciBusHandler(PciType, i, FALSE); + } + } + /* Go to the next bridge */ + } while (HalpGetPciBridgeConfig(PciType, &PciRegistryInfo->NoBuses)); + + /* Now build correct address range informaiton */ + HalpFixupPciSupportedRanges(PciRegistryInfo->NoBuses); + + /* Loop every bus */ + PciSlot.u.bits.Reserved = 0; + for (i = 0; i < PciRegistryInfo->NoBuses; i++) + { + /* Get the bus handler */ + BusHandler = HalHandlerForBus(PCIBus, i); + + /* Loop every device */ + for (j = 0; j < 32; j++) + { + /* Loop every function */ + PciSlot.u.bits.DeviceNumber = j; + for (k = 0; k < 8; k++) + { + /* Build the final slot structure */ + PciSlot.u.bits.FunctionNumber = k; + + /* Read the configuration information */ + HalpReadPCIConfig(BusHandler, + PciSlot, + PciData, + 0, + PCI_COMMON_HDR_LENGTH); + + /* Skip if this is an invalid function */ + if (PciData->VendorID == PCI_INVALID_VENDORID) continue; + + /* Check if this is a Cardbus bridge */ + if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE) + { + /* Not supported */ + DbgPrint("HAL: Your machine has a PCI Cardbus Bridge. This is not supported!\n"); + continue; + } + + /* Check if this is a PCI device */ + if (PCI_CONFIGURATION_TYPE(PciData) != PCI_BRIDGE_TYPE) + { + /* Check if it has an interrupt pin and line registered */ + if ((PciData->u.type1.InterruptPin) && + (PciData->u.type1.InterruptLine)) + { + /* Check if this interrupt line is connected to the bus */ + if (PciData->u.type1.InterruptLine < 16) + { + /* Is this an IDE device? */ + DbgPrint("HAL: Found PCI device with IRQ line\n"); + if (!HalpIsIdeDevice(PciData)) + { + /* We'll mask out this interrupt then */ + DbgPrint("HAL: Device is not an IDE Device. Should be masking IRQ %d! This is not supported!\n", + PciData->u.type1.InterruptLine); + HalpPciIrqMask |= (1 << PciData->u.type1.InterruptLine); + } + } + } + } + + /* Check for broken Intel chips */ + if (PciData->VendorID == 0x8086) + { + /* Check for broken 82830 PCI controller */ + if ((PciData->DeviceID == 0x04A3) && + (PciData->RevisionID < 0x11)) + { + /* Skip */ + DbgPrint("HAL: Your machine has a broken Intel 82430 PCI Controller. This is not supported!\n"); + continue; + } + + /* Check for broken 82378 PCI-to-ISA Bridge */ + if ((PciData->DeviceID == 0x0484) && + (PciData->RevisionID <= 3)) + { + /* Skip */ + DbgPrint("HAL: Your machine has a broken Intel 82378 PCI-to-ISA Bridge. This is not supported!\n"); + continue; + } + + /* Check for broken 82450 PCI Bridge */ + if ((PciData->DeviceID == 0x84C4) && + (PciData->RevisionID <= 4)) + { + DbgPrint("HAL: Your machine has an Intel Orion 82450 PCI Bridge. This is not supported!\n"); + continue; + } + } + + /* Do we know this card? */ + if (!ExtendedAddressDecoding) + { + /* Check for it */ + if (HalpIsRecognizedCard(PciRegistryInfo, PciData, 1)) + { + /* We'll do chipset checks later */ + DbgPrint("HAL: Recognized a PCI Card with Extended Address Decoding. This is not supported!\n"); + ExtendedAddressDecoding = TRUE; + } + } + + /* Check if this is a USB controller */ + if ((PciData->BaseClass == PCI_CLASS_SERIAL_BUS_CTLR) && + (PciData->SubClass == PCI_SUBCLASS_SB_USB)) + { + /* Check if this is an OHCI controller */ + if (PciData->ProgIf == 0x10) + { + DbgPrint("HAL: Your machine has an OHCI (USB) PCI Expansion Card. This is not supported!\n"); + continue; + } + + /* Check for Intel UHCI controller */ + if (PciData->VendorID == 0x8086) + { + DbgPrint("HAL: Your machine has an Intel UHCI (USB) Controller. This is not supported!\n"); + continue; + } + + /* Check for VIA UHCI controller */ + if (PciData->VendorID == 0x1106) + { + DbgPrint("HAL: Your machine has a VIA UHCI (USB) Controller. This is not supported!\n"); + continue; + } + } + + /* Now check the registry for chipset hacks */ + if (NT_SUCCESS(HalpGetChipHacks(PciData->VendorID, + PciData->DeviceID, + PciData->RevisionID, + &HackFlags))) + { + /* Check for hibernate-disable */ + if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE) + { + DbgPrint("HAL: Your machine has a broken PCI device which is incompatible with hibernation. This is not supported!\n"); + continue; + } + + /* Check for USB controllers that generate SMIs */ + if (HackFlags & HAL_PCI_CHIP_HACK_USB_SMI_DISABLE) + { + DbgPrint("HAL: Your machine has a USB controller which generates SMIs. This is not supported!\n"); + continue; + } + } + } + } + } + + /* Initialize NMI Crash Flag */ + HalpGetNMICrashFlag(); + + /* Free the registry data */ + ExFreePool(PciRegistryInfo); + + /* Tell PnP if this hard supports correct decoding */ + HalpMarkChipsetDecode(ExtendedAddressDecoding); + DPRINT1("PCI BUS Setup complete\n"); +#endif +} + +VOID +NTAPI +HalpInitBusHandlers(VOID) +{ + /* Register the HAL Bus Handler support */ + HalpRegisterInternalBusHandlers(); +} + +VOID +NTAPI +HalpRegisterKdSupportFunctions(VOID) +{ + /* Register PCI Device Functions */ + KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging; + KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging; + + /* Register memory functions */ +#ifndef _MINIHAL_ + KdMapPhysicalMemory64 = HalpMapPhysicalMemory64; + KdUnmapVirtualAddress = HalpUnmapVirtualAddress; +#endif + + /* Register ACPI stub */ + KdCheckPowerButton = HalpCheckPowerButton; +} + +NTSTATUS +NTAPI +HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + BUS_HANDLER BusHandler; + PAGED_CODE(); + + /* Only PCI is supported */ + if (BusType != PCIBus) return STATUS_NOT_IMPLEMENTED; + + /* Setup fake PCI Bus handler */ + RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER)); + BusHandler.BusNumber = BusNumber; + + /* Call the PCI function */ + return HalpAssignPCISlotResources(&BusHandler, + &BusHandler, + RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + SlotNumber, + AllocatedResources); +} + +BOOLEAN +NTAPI +HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + /* Translation is easy */ + TranslatedAddress->QuadPart = BusAddress.QuadPart; + return TRUE; +} + +ULONG +NTAPI +HalpGetSystemInterruptVector_Acpi(IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + ULONG Vector = IRQ2VECTOR(BusInterruptLevel); + *Irql = (KIRQL)VECTOR2IRQL(Vector); + *Affinity = 0xFFFFFFFF; + return Vector; +} + +BOOLEAN +NTAPI +HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress, + IN OUT PULONG_PTR Context, + IN BOOLEAN NextBus) +{ + /* Make sure we have a context */ + if (!Context) return FALSE; + + /* If we have data in the context, then this shouldn't be a new lookup */ + if ((*Context) && (NextBus == TRUE)) return FALSE; + + /* Return bus data */ + TranslatedAddress->QuadPart = BusAddress.QuadPart; + + /* Set context value and return success */ + *Context = 1; + return TRUE; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources) +{ + /* Deprecated, return success */ + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +HalAssignSlotResources(IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN INTERFACE_TYPE BusType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + /* Check the bus type */ + if (BusType != PCIBus) + { + /* Call our internal handler */ + return HalpAssignSlotResources(RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + BusType, + BusNumber, + SlotNumber, + AllocatedResources); + } + else + { + /* Call the PCI registered function */ + return HalPciAssignSlotResources(RegistryPath, + DriverClassName, + DriverObject, + DeviceObject, + PCIBus, + BusNumber, + SlotNumber, + AllocatedResources); + } +} + +/* + * @implemented + */ +ULONG +NTAPI +HalGetBusData(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length) +{ + /* Call the extended function */ + return HalGetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + 0, + Length); +} + +/* + * @implemented + */ +ULONG +NTAPI +HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + BUS_HANDLER BusHandler; + + /* Look as the bus type */ + if (BusDataType == Cmos) + { + /* Call CMOS Function */ + return HalpGetCmosData(0, SlotNumber, Buffer, Length); + } + else if (BusDataType == EisaConfiguration) + { + /* FIXME: TODO */ + ASSERT(FALSE); + } + else if ((BusDataType == PCIConfiguration) && + (HalpPCIConfigInitialized) && + ((BusNumber >= HalpMinPciBus) && (BusNumber <= HalpMaxPciBus))) + { + /* Setup fake PCI Bus handler */ + RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER)); + BusHandler.BusNumber = BusNumber; + + /* Call PCI function */ + return HalpGetPCIData(&BusHandler, + &BusHandler, + *(PPCI_SLOT_NUMBER)&SlotNumber, + Buffer, + Offset, + Length); + } + + /* Invalid bus */ + return 0; +} + +/* + * @implemented + */ +ULONG +NTAPI +HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity) +{ + /* Call the system bus translator */ + return HalpGetSystemInterruptVector_Acpi(BusNumber, + BusInterruptLevel, + BusInterruptVector, + Irql, + Affinity); +} + +/* + * @implemented + */ +ULONG +NTAPI +HalSetBusData(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length) +{ + /* Call the extended function */ + return HalSetBusDataByOffset(BusDataType, + BusNumber, + SlotNumber, + Buffer, + 0, + Length); +} + +/* + * @implemented + */ +ULONG +NTAPI +HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + BUS_HANDLER BusHandler; + + /* Look as the bus type */ + if (BusDataType == Cmos) + { + /* Call CMOS Function */ + return HalpSetCmosData(0, SlotNumber, Buffer, Length); + } + else if ((BusDataType == PCIConfiguration) && (HalpPCIConfigInitialized)) + { + /* Setup fake PCI Bus handler */ + RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER)); + BusHandler.BusNumber = BusNumber; + + /* Call PCI function */ + return HalpSetPCIData(&BusHandler, + &BusHandler, + *(PPCI_SLOT_NUMBER)&SlotNumber, + Buffer, + Offset, + Length); + } + + /* Invalid bus */ + return 0; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, + IN ULONG BusNumber, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress) +{ + /* Look as the bus type */ + if (InterfaceType == PCIBus) + { + /* Call the PCI registered function */ + return HalPciTranslateBusAddress(PCIBus, + BusNumber, + BusAddress, + AddressSpace, + TranslatedAddress); + } + else + { + /* Translation is easy */ + TranslatedAddress->QuadPart = BusAddress.QuadPart; + return TRUE; + } +} + +/* EOF */ diff --git a/hal/halx86/generic/legacy/halpcat.c b/hal/halx86/generic/legacy/halpcat.c index ea16403676e..0b85acd54ae 100644 --- a/hal/halx86/generic/legacy/halpcat.c +++ b/hal/halx86/generic/legacy/halpcat.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS HAL * LICENSE: BSD - See COPYING.ARM in the top level directory - * FILE: hal/halx86/generic/acpi/halpcat.c + * FILE: hal/halx86/generic/legacy/halpcat.c * PURPOSE: HAL Legacy Support Code * PROGRAMMERS: ReactOS Portable Systems Group */ @@ -29,19 +29,6 @@ HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock) return STATUS_NO_SUCH_DEVICE; } -VOID -NTAPI -HalpInitializePciBus(VOID) -{ - /* FIXME: Should do legacy PCI bus detection */ - - /* FIXME: Should detect chipset hacks */ - - /* FIXME: Should detect broken PCI hardware and apply hacks */ - - /* FIXME: Should build resource ranges */ -} - VOID NTAPI HalpBuildAddressMap(VOID) diff --git a/hal/halx86/generic/memory.c b/hal/halx86/generic/memory.c new file mode 100644 index 00000000000..74f20cbc6ed --- /dev/null +++ b/hal/halx86/generic/memory.c @@ -0,0 +1,234 @@ +/* + * PROJECT: ReactOS HAL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: hal/halx86/generic/memory.c + * PURPOSE: HAL memory management + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* Share with Mm headers? */ +#define MM_HAL_VA_START (PVOID)0xFFC00000 +#define MM_HAL_HEAP_START (PVOID)((ULONG_PTR)MM_HAL_VA_START + (1024 * 1024)) + +/* GLOBALS *******************************************************************/ + +ULONG HalpUsedAllocDescriptors; +MEMORY_ALLOCATION_DESCRIPTOR HalpAllocationDescriptorArray[64]; +PVOID HalpHeapStart = MM_HAL_HEAP_START; + + +/* PRIVATE FUNCTIONS *********************************************************/ + + +ULONG +NTAPI +HalpAllocPhysicalMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN ULONG MaxAddress, + IN ULONG PageCount, + IN BOOLEAN Aligned) +{ + ULONG UsedDescriptors, Alignment, PhysicalAddress; + PFN_NUMBER MaxPage, BasePage; + PLIST_ENTRY NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock, NewBlock, FreeBlock; + + /* Highest page we'll go */ + MaxPage = MaxAddress >> PAGE_SHIFT; + + /* We need at least two blocks */ + if ((HalpUsedAllocDescriptors + 2) > 64) return 0; + + /* Remember how many we have now */ + UsedDescriptors = HalpUsedAllocDescriptors; + + /* Loop the loader block memory descriptors */ + NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; + while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) + { + /* Get the block */ + MdBlock = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* No alignment by default */ + Alignment = 0; + + /* Unless requested, in which case we use a 64KB block alignment */ + if (Aligned) Alignment = ((MdBlock->BasePage + 0x0F) & ~0x0F) - MdBlock->BasePage; + + /* Search for free memory */ + if ((MdBlock->MemoryType == LoaderFree) || + (MdBlock->MemoryType == LoaderFirmwareTemporary)) + { + /* Make sure the page is within bounds, including alignment */ + BasePage = MdBlock->BasePage; + if ((BasePage) && + (MdBlock->PageCount >= PageCount + Alignment) && + (BasePage + PageCount + Alignment < MaxPage)) + { + + /* We found an address */ + PhysicalAddress = (BasePage + Alignment) << PAGE_SHIFT; + break; + } + } + + /* Keep trying */ + NextEntry = NextEntry->Flink; + } + + /* If we didn't find anything, get out of here */ + if (NextEntry == &LoaderBlock->MemoryDescriptorListHead) return 0; + + /* Okay, now get a descriptor */ + NewBlock = &HalpAllocationDescriptorArray[HalpUsedAllocDescriptors]; + NewBlock->PageCount = PageCount; + NewBlock->BasePage = MdBlock->BasePage + Alignment; + NewBlock->MemoryType = LoaderHALCachedMemory; + + /* Update count */ + UsedDescriptors++; + HalpUsedAllocDescriptors = UsedDescriptors; + + /* Check if we had any alignment */ + if (Alignment) + { + /* Check if we had leftovers */ + if ((MdBlock->PageCount - Alignment) != PageCount) + { + /* Get the next descriptor */ + FreeBlock = &HalpAllocationDescriptorArray[UsedDescriptors]; + FreeBlock->PageCount = MdBlock->PageCount - Alignment - PageCount; + FreeBlock->BasePage = MdBlock->BasePage + Alignment + PageCount; + + /* One more */ + HalpUsedAllocDescriptors++; + + /* Insert it into the list */ + InsertHeadList(&MdBlock->ListEntry, &FreeBlock->ListEntry); + } + + /* Use this descriptor */ + NewBlock->PageCount = Alignment; + InsertHeadList(&MdBlock->ListEntry, &NewBlock->ListEntry); + } + else + { + /* Consume memory from this block */ + MdBlock->BasePage += PageCount; + MdBlock->PageCount -= PageCount; + + /* Insert the descriptor */ + InsertTailList(&MdBlock->ListEntry, &NewBlock->ListEntry); + + /* Remove the entry if the whole block was allocated */ + if (!MdBlock->PageCount == 0) RemoveEntryList(&MdBlock->ListEntry); + } + + /* Return the address */ + return PhysicalAddress; +} + +PVOID +NTAPI +HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG PageCount) +{ + PHARDWARE_PTE PointerPte; + ULONG UsedPages = 0; + PVOID VirtualAddress, BaseAddress; + + /* Start at the current HAL heap base */ + BaseAddress = HalpHeapStart; + VirtualAddress = BaseAddress; + + /* Loop until we have all the pages required */ + while (UsedPages < PageCount) + { + /* If this overflows past the HAL heap, it means there's no space */ + if (VirtualAddress == NULL) return NULL; + + /* Get the PTE for this address */ + PointerPte = HalAddressToPte(VirtualAddress); + + /* Go to the next page */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); + + /* Check if the page is available */ + if (PointerPte->Valid) + { + /* PTE has data, skip it and start with a new base address */ + BaseAddress = VirtualAddress; + UsedPages = 0; + continue; + } + + /* PTE is available, keep going on this run */ + UsedPages++; + } + + /* Take the base address of the page plus the actual offset in the address */ + VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress + + BYTE_OFFSET(PhysicalAddress.LowPart)); + + /* If we are starting at the heap, move the heap */ + if (BaseAddress == HalpHeapStart) + { + /* Past this allocation */ + HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE)); + } + + /* Loop pages that can be mapped */ + while (UsedPages--) + { + /* Fill out the PTE */ + PointerPte = HalAddressToPte(BaseAddress); + PointerPte->PageFrameNumber = PhysicalAddress.QuadPart >> PAGE_SHIFT; + PointerPte->Valid = 1; + PointerPte->Write = 1; + + /* Move to the next address */ + PhysicalAddress.QuadPart += PAGE_SIZE; + BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE); + } + + /* Flush the TLB and return the address */ + HalpFlushTLB(); + return VirtualAddress; +} + +VOID +NTAPI +HalpUnmapVirtualAddress(IN PVOID VirtualAddress, + IN ULONG PageCount) +{ + PHARDWARE_PTE PointerPte; + ULONG i; + + /* Only accept valid addresses */ + if (VirtualAddress < MM_HAL_VA_START) return; + + /* Align it down to page size */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1)); + + /* Loop PTEs */ + PointerPte = HalAddressToPte(VirtualAddress); + for (i = 0; i < PageCount; i++) + { + *(PULONG)PointerPte = 0; + PointerPte++; + } + + /* Flush the TLB */ + HalpFlushTLB(); + + /* Put the heap back */ + if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress; +} + diff --git a/hal/halx86/generic/timer.c b/hal/halx86/generic/timer.c index 6d90dada9b8..524b6cecb34 100644 --- a/hal/halx86/generic/timer.c +++ b/hal/halx86/generic/timer.c @@ -109,6 +109,7 @@ HalpInitializeClock(VOID) HalpCurrentRollOver = RollOver; } +#ifdef _M_IX86 #ifndef _MINIHAL_ VOID FASTCALL @@ -163,6 +164,7 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame) } #endif +#endif /* PUBLIC FUNCTIONS ***********************************************************/ diff --git a/hal/halx86/generic/usage.c b/hal/halx86/generic/usage.c index 02c86e2a046..c35df96c3e5 100644 --- a/hal/halx86/generic/usage.c +++ b/hal/halx86/generic/usage.c @@ -509,17 +509,11 @@ HalpEnableInterruptHandler(IN UCHAR Flags, IN PVOID Handler, IN KINTERRUPT_MODE Mode) { - UCHAR Entry; - - /* Convert the vector into the IDT entry */ - Entry = HalVectorToIDTEntry(SystemVector); - /* Register the vector */ HalpRegisterVector(Flags, BusVector, SystemVector, Irql); /* Connect the interrupt */ - ((PKIPCR)KeGetPcr())->IDT[Entry].ExtendedOffset = (USHORT)(((ULONG_PTR)Handler >> 16) & 0xFFFF); - ((PKIPCR)KeGetPcr())->IDT[Entry].Offset = (USHORT)((ULONG_PTR)Handler); + KeRegisterInterruptHandler(SystemVector, Handler); /* Enable the interrupt */ HalEnableSystemInterrupt(SystemVector, Irql, Mode); diff --git a/hal/halx86/hal_generic.rbuild b/hal/halx86/hal_generic.rbuild index 3532d001d18..0cd4e5aac43 100644 --- a/hal/halx86/hal_generic.rbuild +++ b/hal/halx86/hal_generic.rbuild @@ -7,20 +7,12 @@ - - bushndlr.c - isabus.c - halbus.c - pcibus.c - pcidata.c - sysbus.c - beep.c cmos.c display.c dma.c drive.c - halinit.c + memory.c misc.c profil.c reboot.c @@ -29,25 +21,13 @@ usage.c bios.c + halinit.c portio.c systimer.S trap.S - - - - - x86bios.c - - - - - systimer.S - - - hal.h diff --git a/hal/halx86/hal_generic_acpi.rbuild b/hal/halx86/hal_generic_acpi.rbuild index 3784394b642..97501cb1823 100644 --- a/hal/halx86/hal_generic_acpi.rbuild +++ b/hal/halx86/hal_generic_acpi.rbuild @@ -10,7 +10,13 @@ halacpi.c halpnpdd.c + busemul.c + + + pcibus.c + + diff --git a/hal/halx86/hal_generic_pcat.rbuild b/hal/halx86/hal_generic_pcat.rbuild index e00ed5bdb4e..51f46eefc71 100644 --- a/hal/halx86/hal_generic_pcat.rbuild +++ b/hal/halx86/hal_generic_pcat.rbuild @@ -8,6 +8,15 @@ + + bushndlr.c + cmosbus.c + isabus.c + pcibus.c + pcidata.c + sysbus.c + + bussupp.c halpcat.c diff --git a/hal/halx86/hal_mini.rbuild b/hal/halx86/hal_mini.rbuild index a7baed44639..b2c8b718735 100644 --- a/hal/halx86/hal_mini.rbuild +++ b/hal/halx86/hal_mini.rbuild @@ -9,13 +9,16 @@ - - bushndlr.c - isabus.c - halbus.c - pcibus.c - pcidata.c - sysbus.c + + + bushndlr.c + cmosbus.c + isabus.c + pcibus.c + pcidata.c + sysbus.c + + bussupp.c beep.c bios.c diff --git a/hal/halx86/halamd64.rbuild b/hal/halx86/halamd64.rbuild index 92c4f29983d..02f633c9fd0 100644 --- a/hal/halx86/halamd64.rbuild +++ b/hal/halx86/halamd64.rbuild @@ -8,6 +8,7 @@ include + hal_generic @@ -19,18 +20,14 @@ spinlock.c - + + x86bios.c + halinit.c + stubs.c + systimer.S processor.c - diff --git a/hal/halx86/include/bus.h b/hal/halx86/include/bus.h index 03840227411..38cf406bf13 100644 --- a/hal/halx86/include/bus.h +++ b/hal/halx86/include/bus.h @@ -205,6 +205,18 @@ typedef struct _HAL_BUS_HANDLER /* FUNCTIONS *****************************************************************/ +/* SHARED (Fake PCI-BUS HANDLER) */ + +extern PCI_CONFIG_HANDLER PCIConfigHandler; +extern PCI_CONFIG_HANDLER PCIConfigHandlerType1; +extern PCI_CONFIG_HANDLER PCIConfigHandlerType2; + +PPCI_REGISTRY_INFO_INTERNAL +NTAPI +HalpQueryPciRegistryInfo( + VOID +); + VOID NTAPI HalpPCISynchronizeType1( @@ -277,34 +289,6 @@ HalpWritePCIConfig( IN ULONG Length ); -ULONG -NTAPI -HalpGetSystemInterruptVector( - ULONG BusNumber, - ULONG BusInterruptLevel, - ULONG BusInterruptVector, - PKIRQL Irql, - PKAFFINITY Affinity -); - -ULONG -NTAPI -HalpGetCmosData( - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length -); - -ULONG -NTAPI -HalpSetCmosData( - IN ULONG BusNumber, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Length -); - ULONG NTAPI HalpGetPCIData( @@ -340,6 +324,36 @@ HalpAssignPCISlotResources( IN OUT PCM_RESOURCE_LIST *pAllocatedResources ); +/* NON-LEGACY */ + +ULONG +NTAPI +HalpGetSystemInterruptVector_Acpi( + ULONG BusNumber, + ULONG BusInterruptLevel, + ULONG BusInterruptVector, + PKIRQL Irql, + PKAFFINITY Affinity +); + +ULONG +NTAPI +HalpGetCmosData( + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length +); + +ULONG +NTAPI +HalpSetCmosData( + IN ULONG BusNumber, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Length +); + VOID NTAPI HalpInitializePciBus( @@ -352,12 +366,6 @@ HalpInitializePciStubs( VOID ); -VOID -NTAPI -HalpInitBusHandler( - VOID -); - BOOLEAN NTAPI HalpTranslateBusAddress( @@ -397,6 +405,114 @@ HalpRegisterPciDebuggingDeviceInfo( VOID ); +/* LEGACY */ + +NTSTATUS +NTAPI +HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList); + +ULONG +NTAPI +HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity); +VOID +NTAPI +HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciData); + +VOID +NTAPI +HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER SlotNumber, + IN PPCI_COMMON_CONFIG PciNewData, + IN PPCI_COMMON_CONFIG PciOldData); + +NTSTATUS +NTAPI +HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PCI_SLOT_NUMBER PciSlot, + OUT PSUPPORTED_RANGE *Range); + +VOID +NTAPI +HalpInitBusHandler( + VOID +); + +ULONG +NTAPI +HalpNoBusData( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length +); + +ULONG +NTAPI +HalpcGetCmosData( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length +); + +ULONG +NTAPI +HalpcSetCmosData( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length +); + +BOOLEAN +NTAPI +HalpTranslateSystemBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress +); + +BOOLEAN +NTAPI +HalpTranslateIsaBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress +); + +ULONG +NTAPI +HalpGetSystemInterruptVector( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity +); + extern ULONG HalpBusType; extern BOOLEAN HalpPCIConfigInitialized; extern BUS_HANDLER HalpFakePciBusHandler; diff --git a/hal/halx86/include/hal.h b/hal/halx86/include/hal.h index 97e8f4a810e..0c3654f5ff8 100644 --- a/hal/halx86/include/hal.h +++ b/hal/halx86/include/hal.h @@ -32,11 +32,13 @@ /* Internal kernel headers */ #include "internal/pci.h" #define KeGetCurrentThread _KeGetCurrentThread -#include -#include #ifdef _M_AMD64 +#include +#include #include "internal/amd64/intrin_i.h" #else +#include +#include #include "internal/i386/intrin_i.h" #endif diff --git a/hal/halx86/include/halp.h b/hal/halx86/include/halp.h index 6edb85570d7..aa36554c7ec 100644 --- a/hal/halx86/include/halp.h +++ b/hal/halx86/include/halp.h @@ -765,6 +765,12 @@ KeUpdateSystemTime( IN KIRQL OldIrql ); +VOID +NTAPI +HalpInitBusHandlers( + VOID +); + #ifdef _M_AMD64 #define KfLowerIrql KeLowerIrql #ifndef CONFIG_SMP diff --git a/hal/halx86/up/pic.c b/hal/halx86/up/pic.c index a710d862567..91b902b1a35 100644 --- a/hal/halx86/up/pic.c +++ b/hal/halx86/up/pic.c @@ -94,8 +94,8 @@ PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16] = /* This table contains the static x86 PIC mapping between IRQLs and IRQs */ ULONG KiI8259MaskTable[32] = { -#ifdef __GNUC__ -#if __GNUC__ * 100 + __GNUC_MINOR__ >= 404 +#if defined(__GNUC__) && \ + (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) /* * It Device IRQLs only start at 4 or higher, so these are just software * IRQLs that don't really change anything on the hardware @@ -206,14 +206,13 @@ ULONG KiI8259MaskTable[32] = 0xFFFFFFFB, /* IRQL 30 */ 0xFFFFFFFB /* IRQL 31 */ #endif -#endif }; /* This table indicates which IRQs, if pending, can preempt a given IRQL level */ ULONG FindHigherIrqlMask[32] = { -#ifdef __GNUC__ -#if __GNUC__ * 100 + __GNUC_MINOR__ >= 404 +#if defined(__GNUC__) && \ + (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) /* * Software IRQLs, at these levels all hardware interrupts can preempt. * Each higher IRQL simply enables which software IRQL can preempt the @@ -313,7 +312,6 @@ ULONG FindHigherIrqlMask[32] = 0, /* IRQL 30 */ 0 /* IRQL 31 */ #endif -#endif }; /* Denotes minimum required IRQL before we can process pending SW interrupts */ @@ -329,6 +327,8 @@ KIRQL SWInterruptLookUpTable[8] = DISPATCH_LEVEL /* IRR 7 */ }; +#if defined(__GNUC__) + #define HalpDelayedHardwareInterrupt(x) \ VOID HalpHardwareInterrupt##x(VOID); \ VOID \ @@ -337,6 +337,23 @@ KIRQL SWInterruptLookUpTable[8] = asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x)); \ } +#elif defined(_MSC_VER) + +#define HalpDelayedHardwareInterrupt(x) \ + VOID HalpHardwareInterrupt##x(VOID); \ + VOID \ + HalpHardwareInterrupt##x(VOID) \ + { \ + __asm \ + { \ + int PRIMARY_VECTOR_BASE + x \ + } \ + } + +#else +#error Unsupported compiler +#endif + /* Pending/delayed hardware interrupt handlers */ HalpDelayedHardwareInterrupt(0); HalpDelayedHardwareInterrupt(1); @@ -522,7 +539,7 @@ KeRaiseIrqlToDpcLevel(VOID) CurrentIrql = Pcr->Irql; Pcr->Irql = DISPATCH_LEVEL; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct raise */ if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL); #endif @@ -545,7 +562,7 @@ KeRaiseIrqlToSynchLevel(VOID) CurrentIrql = Pcr->Irql; Pcr->Irql = SYNCH_LEVEL; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct raise */ if (CurrentIrql > SYNCH_LEVEL) { @@ -575,7 +592,7 @@ KfRaiseIrql(IN KIRQL NewIrql) /* Read current IRQL */ CurrentIrql = Pcr->Irql; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct raise */ if (CurrentIrql > NewIrql) { @@ -605,7 +622,7 @@ KfLowerIrql(IN KIRQL OldIrql) PKPCR Pcr = KeGetPcr(); PIC_MASK Mask; -#ifdef IRQL_DEBUG +#if DBG /* Validate correct lower */ if (OldIrql > Pcr->Irql) { diff --git a/include/crt/_mingw.h b/include/crt/_mingw.h index d4e53ff435a..cff811248d8 100644 --- a/include/crt/_mingw.h +++ b/include/crt/_mingw.h @@ -157,10 +157,12 @@ allow GCC to optimize away some EH unwind code, at least in DW2 case. */ //#endif #ifdef __GNUC__ +#ifndef __clang__ #define __int8 char #define __int16 short #define __int32 int #define __int64 long long +#endif #ifdef _WIN64 typedef int __int128 __attribute__ ((mode (TI))); # endif diff --git a/include/crt/assert.h b/include/crt/assert.h index 252fd54a269..9107ee5a272 100644 --- a/include/crt/assert.h +++ b/include/crt/assert.h @@ -28,8 +28,7 @@ extern "C" { #endif #ifndef assert -//#define assert(_Expression) (void)((!!(_Expression)) || (_assert(#_Expression,__FILE__,__LINE__),0)) -#define assert(_Expression) (void)((!!(_Expression)))// || (_wassert(_CRT_WIDE(#_Expression),_CRT_WIDE(__FILE__),__LINE__),0)) +#define assert(_Expression) (void)((!!(_Expression)) || (_assert(#_Expression,__FILE__,__LINE__),0)) #endif #ifndef wassert diff --git a/include/crt/math.h b/include/crt/math.h index 9b645c15a51..fe4b4bc65b8 100644 --- a/include/crt/math.h +++ b/include/crt/math.h @@ -435,8 +435,6 @@ __CRT_INLINE int isinf (double d) { return res; } - extern long double __cdecl modfl (long double, long double*); - /* 7.12.6.13 */ extern double __cdecl scalbn (double, int); extern float __cdecl scalbnf (float, int); @@ -458,7 +456,6 @@ __CRT_INLINE int isinf (double d) { extern long double __cdecl expl(long double); extern long double expm1l(long double); extern long double __cdecl coshl(long double); - extern long double __cdecl fabsl (long double); extern long double __cdecl acosl(long double); extern long double __cdecl asinl(long double); extern long double __cdecl atanl(long double); diff --git a/include/crt/mingw32/intrin_x86.h b/include/crt/mingw32/intrin_x86.h index 9e83ed81838..5b6f32d18a3 100644 --- a/include/crt/mingw32/intrin_x86.h +++ b/include/crt/mingw32/intrin_x86.h @@ -114,7 +114,7 @@ __INTRIN_INLINE long _InterlockedCompareExchange(volatile long * const Destinati __INTRIN_INLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand) { - return __sync_val_compare_and_swap(Destination, Comperand, Exchange); + return (void *)__sync_val_compare_and_swap(Destination, Comperand, Exchange); } __INTRIN_INLINE long _InterlockedExchange(volatile long * const Target, const long Value) @@ -137,7 +137,7 @@ __INTRIN_INLINE void * _InterlockedExchangePointer(void * volatile * const Targe { /* NOTE: ditto */ __sync_synchronize(); - return __sync_lock_test_and_set(Target, Value); + return (void *)__sync_lock_test_and_set(Target, Value); } __INTRIN_INLINE long _InterlockedExchangeAdd16(volatile short * const Addend, const short Value) diff --git a/include/crt/sec_api/wchar_s.h b/include/crt/sec_api/wchar_s.h index 94251aa8b64..8a3ea3739d5 100644 --- a/include/crt/sec_api/wchar_s.h +++ b/include/crt/sec_api/wchar_s.h @@ -96,16 +96,6 @@ extern "C" { _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale); #endif -#ifndef _WTIME_S_DEFINED -#define _WTIME_S_DEFINED - _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); - _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); - _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); - _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); -#if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); -#endif - #if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) #define _INC_WTIME_S_INL #ifdef _USE_32BIT_TIME_T diff --git a/include/crt/stdlib.h b/include/crt/stdlib.h index d4846fa2c71..0efd5cc4321 100644 --- a/include/crt/stdlib.h +++ b/include/crt/stdlib.h @@ -345,11 +345,15 @@ extern "C" { void *__cdecl bsearch(const void *_Key,const void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); void __cdecl qsort(void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); #endif + +#if !defined(__GNUC__) && !defined(__clang) unsigned short __cdecl _byteswap_ushort(unsigned short _Short); - /*unsigned long __cdecl _byteswap_ulong (unsigned long _Long); */ + unsigned long __cdecl _byteswap_ulong (unsigned long _Long); #if _INTEGRAL_MAX_BITS >= 64 __MINGW_EXTENSION unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 _Int64); #endif +#endif + div_t __cdecl div(int _Numerator,int _Denominator); char *__cdecl getenv(const char *_VarName); _CRTIMP char *__cdecl _itoa(int _Value,char *_Dest,int _Radix); @@ -478,6 +482,7 @@ extern "C" { void __cdecl perror(const char *_ErrMsg); #endif _CRTIMP int __cdecl _putenv(const char *_EnvString); +#if !defined(__GNUC__) && !defined(__clang) unsigned int __cdecl _rotl(unsigned int _Val,int _Shift); #if _INTEGRAL_MAX_BITS >= 64 __MINGW_EXTENSION unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val,int _Shift); @@ -485,6 +490,7 @@ extern "C" { unsigned int __cdecl _rotr(unsigned int _Val,int _Shift); #if _INTEGRAL_MAX_BITS >= 64 __MINGW_EXTENSION unsigned __int64 __cdecl _rotr64(unsigned __int64 _Val,int _Shift); +#endif #endif _CRTIMP void __cdecl _searchenv(const char *_Filename,const char *_EnvVar,char *_ResultPath); _CRTIMP void __cdecl _splitpath(const char *_FullPath,char *_Drive,char *_Dir,char *_Filename,char *_Ext); diff --git a/include/crt/time.h b/include/crt/time.h index 75da425e3a1..5cf88adf7c9 100644 --- a/include/crt/time.h +++ b/include/crt/time.h @@ -114,6 +114,7 @@ extern "C" { _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(struct tm *_Tm); _CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec); + _CRTIMP errno_t __cdecl asctime_s(char *_Buf,size_t _SizeInWords,const struct tm *_Tm); _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); @@ -184,6 +185,7 @@ __CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _diff __CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime32(_Time); } __CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime32(_Time); } __CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime32(_Time); } +__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); } __CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime32(_Tm); } __CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); } __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time32(_Time); } @@ -193,6 +195,7 @@ __CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _diff __CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime64(_Time); } __CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime64(_Time); } __CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime64(_Time); } +__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); } __CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime64(_Tm); } __CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); } __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } @@ -214,7 +217,5 @@ __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } #pragma pack(pop) -#include - #endif /* End _TIME_H_ */ diff --git a/include/crt/wchar.h b/include/crt/wchar.h index f70dfbbc6a2..364b1697534 100644 --- a/include/crt/wchar.h +++ b/include/crt/wchar.h @@ -751,19 +751,27 @@ _CRTIMP int __cdecl iswblank(wint_t _C); _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale); _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer); _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer); + + _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); + _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); + #if _INTEGRAL_MAX_BITS >= 64 _CRTIMP wchar_t *__cdecl _wctime64(const __time64_t *_Time); + _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); #endif #if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) #define _INC_WTIME_INL #ifdef _USE_32BIT_TIME_T __CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); } -#else +#else /* !_USE_32BIT_TIME_T */ __CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); } -#endif -#endif -#endif +#endif /* !_USE_32BIT_TIME_T */ +#endif /* !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) */ + +#endif /* _WTIME_DEFINED */ typedef int mbstate_t; typedef wchar_t _Wint_t; diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h index c05458e81f2..7c91023e6d6 100644 --- a/include/ddk/ntifs.h +++ b/include/ddk/ntifs.h @@ -6188,6 +6188,20 @@ typedef LBN *PLBN; typedef ULONG VBN; typedef VBN *PVBN; +#define FSRTL_COMMON_FCB_HEADER_LAYOUT \ + CSHORT NodeTypeCode; \ + CSHORT NodeByteSize; \ + UCHAR Flags; \ + UCHAR IsFastIoPossible; \ + UCHAR Flags2; \ + UCHAR Reserved:4; \ + UCHAR Version:4; \ + PERESOURCE Resource; \ + PERESOURCE PagingIoResource; \ + LARGE_INTEGER AllocationSize; \ + LARGE_INTEGER FileSize; \ + LARGE_INTEGER ValidDataLength; + #define FSRTL_COMMON_FCB_HEADER_LAYOUT \ CSHORT NodeTypeCode; \ CSHORT NodeByteSize; \ diff --git a/include/ddk/ntstrsafe.h b/include/ddk/ntstrsafe.h index d5a02cb1bf7..447a3a5265c 100644 --- a/include/ddk/ntstrsafe.h +++ b/include/ddk/ntstrsafe.h @@ -36,7 +36,7 @@ typedef unsigned long DWORD; __inline NTSTATUS NTAPI -RtlStringLengthWorkerA(IN PCHAR String, +RtlStringLengthWorkerA(IN LPCSTR String, IN SIZE_T MaxLength, OUT PSIZE_T ReturnLength OPTIONAL) { @@ -69,7 +69,7 @@ RtlStringLengthWorkerA(IN PCHAR String, __inline NTSTATUS NTAPI -RtlStringValidateDestA(IN PCHAR Destination, +RtlStringValidateDestA(IN LPSTR Destination, IN SIZE_T Length, OUT PSIZE_T ReturnLength OPTIONAL, IN SIZE_T MaxLength) @@ -98,7 +98,7 @@ RtlStringValidateDestA(IN PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringExValidateDestA(IN OUT PCHAR *Destination, +RtlStringExValidateDestA(IN OUT LPSTR *Destination, IN OUT PSIZE_T DestinationLength, OUT PSIZE_T ReturnLength OPTIONAL, IN SIZE_T MaxLength, @@ -114,7 +114,7 @@ RtlStringExValidateDestA(IN OUT PCHAR *Destination, __inline NTSTATUS NTAPI -RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL, +RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, IN OUT PSIZE_T ReturnLength OPTIONAL, IN SIZE_T MaxLength, IN DWORD Flags) @@ -133,10 +133,10 @@ RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL, __inline NTSTATUS NTAPI -RtlStringVPrintfWorkerA(OUT PCHAR Destination, +RtlStringVPrintfWorkerA(OUT LPSTR Destination, IN SIZE_T Length, OUT PSIZE_T NewLength OPTIONAL, - IN PCCHAR Format, + IN LPCSTR Format, IN va_list argList) { NTSTATUS Status = STATUS_SUCCESS; @@ -174,10 +174,10 @@ RtlStringVPrintfWorkerA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCopyWorkerA(OUT PCHAR Destination, +RtlStringCopyWorkerA(OUT LPSTR Destination, IN SIZE_T Length, OUT PSIZE_T NewLength OPTIONAL, - IN PCCHAR Source, + IN LPCSTR Source, IN SIZE_T CopyLength) { NTSTATUS Status = STATUS_SUCCESS; @@ -211,9 +211,9 @@ RtlStringCopyWorkerA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCchCopyA(IN PCHAR Destination, +RtlStringCchCopyA(IN LPSTR Destination, IN SIZE_T cchDest, - IN PCCHAR pszSrc) + IN LPCSTR pszSrc) { ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE); return STATUS_NOT_IMPLEMENTED; @@ -222,9 +222,9 @@ RtlStringCchCopyA(IN PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbPrintfA(OUT PCHAR Destination, +RtlStringCbPrintfA(OUT LPSTR Destination, IN SIZE_T Length, - IN PCHAR Format, + IN LPCSTR Format, ...) { NTSTATUS Status; @@ -252,12 +252,12 @@ RtlStringCbPrintfA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbPrintfExA(OUT PCHAR Destination, +RtlStringCbPrintfExA(OUT LPSTR Destination, IN SIZE_T Length, - OUT PCHAR *DestinationEnd OPTIONAL, + OUT LPSTR *DestinationEnd OPTIONAL, OUT PSIZE_T RemainingSize OPTIONAL, IN DWORD Flags, - IN PCCHAR Format, + IN LPCSTR Format, ...) { NTSTATUS Status; @@ -333,10 +333,10 @@ RtlStringCbPrintfExA(OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbCopyExA(OUT PCHAR Destination, +RtlStringCbCopyExA(OUT LPSTR Destination, IN SIZE_T Length, - IN PCCHAR Source, - OUT PCHAR *DestinationEnd OPTIONAL, + IN LPCSTR Source, + OUT LPSTR *DestinationEnd OPTIONAL, OUT PSIZE_T RemainingSize OPTIONAL, IN DWORD Flags) { @@ -423,10 +423,10 @@ RtlStringCbPrintfW( __inline NTSTATUS NTAPI -RtlStringCbCatExA(IN OUT PCHAR Destination, +RtlStringCbCatExA(IN OUT LPSTR Destination, IN SIZE_T Length, - IN PCCHAR Source, - OUT PCHAR *DestinationEnd OPTIONAL, + IN LPCSTR Source, + OUT LPSTR *DestinationEnd OPTIONAL, OUT PSIZE_T RemainingSize OPTIONAL, IN DWORD Flags) { @@ -497,9 +497,9 @@ RtlStringCbCatExA(IN OUT PCHAR Destination, __inline NTSTATUS NTAPI -RtlStringCbCopyA(OUT PCHAR Destination, +RtlStringCbCopyA(OUT LPSTR Destination, IN SIZE_T Length, - IN PCCHAR Source) + IN LPCSTR Source) { NTSTATUS Status; SIZE_T CharLength = Length / sizeof(CHAR); diff --git a/include/dxsdk/ksguid.h b/include/dxsdk/ksguid.h index 84b1e59487c..51b1bb38a36 100644 --- a/include/dxsdk/ksguid.h +++ b/include/dxsdk/ksguid.h @@ -6,7 +6,7 @@ #endif #if !defined( DEFINE_WAVEFORMATEX_GUID ) - #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } #endif #if defined( DEFINE_GUIDEX ) diff --git a/include/ndk/pstypes.h b/include/ndk/pstypes.h index 43b44680960..414e2dcbec1 100644 --- a/include/ndk/pstypes.h +++ b/include/ndk/pstypes.h @@ -60,7 +60,11 @@ Author: #define FLG_ENABLE_CSRDEBUG 0x00020000 #define FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000 #define FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000 +#if (NTDDI_VERSION < NTDDI_WINXP) #define FLG_HEAP_ENABLE_CALL_TRACING 0x00100000 +#else +#define FLG_ENABLE_SYSTEM_CRIT_BREAKS 0x00100000 +#endif #define FLG_HEAP_DISABLE_COALESCING 0x00200000 #define FLG_ENABLE_CLOSE_EXCEPTIONS 0x00400000 #define FLG_ENABLE_EXCEPTION_LOGGING 0x00800000 diff --git a/include/ndk/rtlfuncs.h b/include/ndk/rtlfuncs.h index 18aa4749ad4..d0f3f06d701 100644 --- a/include/ndk/rtlfuncs.h +++ b/include/ndk/rtlfuncs.h @@ -2042,12 +2042,12 @@ RtlRemoteCall( ); NTSYSAPI -VOID +NTSTATUS NTAPI RtlSetProcessIsCritical( IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, - IN BOOLEAN IsWinlogon + IN BOOLEAN NeedBreaks ); NTSYSAPI diff --git a/include/psdk/commctrl.h b/include/psdk/commctrl.h index 9f3366e3474..bc452a2f9db 100644 --- a/include/psdk/commctrl.h +++ b/include/psdk/commctrl.h @@ -2240,6 +2240,7 @@ extern "C" { #define LVSIL_NORMAL 0 #define LVSIL_SMALL 1 #define LVSIL_STATE 2 +#define LVSIL_GROUPHEADER 3 #define LVM_SETIMAGELIST (LVM_FIRST+3) #define ListView_SetImageList(hwnd,himl,iImageList) (HIMAGELIST)SNDMSG((hwnd),LVM_SETIMAGELIST,(WPARAM)(iImageList),(LPARAM)(HIMAGELIST)(himl)) @@ -2392,6 +2393,7 @@ extern "C" { #define LVFI_PARAM 0x1 #define LVFI_STRING 0x2 +#define LVFI_SUBSTRING 0x4 #define LVFI_PARTIAL 0x8 #define LVFI_WRAP 0x20 #define LVFI_NEARESTXY 0x40 @@ -4380,6 +4382,8 @@ typedef struct tagTVDISPINFOEXW { SYSTEMTIME st; } MCHITTESTINFO,*PMCHITTESTINFO; +#define MCHITTESTINFO_V1_SIZE CCSIZEOF_STRUCT(MCHITTESTINFO, st) + #define MCHT_TITLE 0x10000 #define MCHT_CALENDAR 0x20000 #define MCHT_TODAYLINK 0x30000 diff --git a/include/psdk/ks.h b/include/psdk/ks.h index 2290d7cf4e2..62357d623a1 100644 --- a/include/psdk/ks.h +++ b/include/psdk/ks.h @@ -166,77 +166,77 @@ DEFINE_GUIDSTRUCT("d833f8f8-7894-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_P */ #define STATIC_KSCATEGORY_BRIDGE \ - 0x085AFF00L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x085AFF00L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("085AFF00-62CE-11CF-A5D6-28DB04C10000", KSCATEGORY_BRIDGE); #define KSCATEGORY_BRIDGE DEFINE_GUIDNAMED(KSCATEGORY_BRIDGE) #define STATIC_KSCATEGORY_CAPTURE \ - 0x65E8773DL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("65E8773D-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_CAPTURE); #define KSCATEGORY_CAPTURE DEFINE_GUIDNAMED(KSCATEGORY_CAPTURE) #define STATIC_KSCATEGORY_RENDER \ - 0x65E8773EL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("65E8773E-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_RENDER); #define KSCATEGORY_RENDER DEFINE_GUIDNAMED(KSCATEGORY_RENDER) #define STATIC_KSCATEGORY_MIXER \ - 0xAD809C00L, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0xAD809C00L, 0x7B88, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("AD809C00-7B88-11D0-A5D6-28DB04C10000", KSCATEGORY_MIXER); #define KSCATEGORY_MIXER DEFINE_GUIDNAMED(KSCATEGORY_MIXER) #define STATIC_KSCATEGORY_SPLITTER \ - 0x0A4252A0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x0A4252A0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("0A4252A0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_SPLITTER); #define KSCATEGORY_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_SPLITTER) #define STATIC_KSCATEGORY_DATACOMPRESSOR \ - 0x1E84C900L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x1E84C900L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("1E84C900-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATACOMPRESSOR); #define KSCATEGORY_DATACOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATACOMPRESSOR) #define STATIC_KSCATEGORY_DATADECOMPRESSOR \ - 0x2721AE20L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x2721AE20L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("2721AE20-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATADECOMPRESSOR); #define KSCATEGORY_DATADECOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATADECOMPRESSOR) #define STATIC_KSCATEGORY_DATATRANSFORM \ - 0x2EB07EA0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x2EB07EA0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("2EB07EA0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATATRANSFORM); #define KSCATEGORY_DATATRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_DATATRANSFORM) #define STATIC_KSCATEGORY_COMMUNICATIONSTRANSFORM \ - 0xCF1DDA2CL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xCF1DDA2CL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("CF1DDA2C-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_COMMUNICATIONSTRANSFORM); #define KSCATEGORY_COMMUNICATIONSTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_COMMUNICATIONSTRANSFORM) #define STATIC_KSCATEGORY_INTERFACETRANSFORM \ - 0xCF1DDA2DL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xCF1DDA2DL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("CF1DDA2D-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_INTERFACETRANSFORM); #define KSCATEGORY_INTERFACETRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_INTERFACETRANSFORM) #define STATIC_KSCATEGORY_MEDIUMTRANSFORM \ - 0xCF1DDA2EL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xCF1DDA2EL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("CF1DDA2E-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_MEDIUMTRANSFORM); #define KSCATEGORY_MEDIUMTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_MEDIUMTRANSFORM) #define STATIC_KSCATEGORY_FILESYSTEM \ - 0x760FED5EL, 0x9357, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x760FED5EL, 0x9357, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("760FED5E-9357-11D0-A3CC-00A0C9223196", KSCATEGORY_FILESYSTEM); #define KSCATEGORY_FILESYSTEM DEFINE_GUIDNAMED(KSCATEGORY_FILESYSTEM) #define STATIC_KSCATEGORY_CLOCK \ - 0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x53172480L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSCATEGORY_CLOCK); #define KSCATEGORY_CLOCK DEFINE_GUIDNAMED(KSCATEGORY_CLOCK) #define STATIC_KSCATEGORY_PROXY \ - 0x97EBAACAL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x97EBAACAL, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("97EBAACA-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_PROXY); #define KSCATEGORY_PROXY DEFINE_GUIDNAMED(KSCATEGORY_PROXY) #define STATIC_KSCATEGORY_QUALITY \ - 0x97EBAACBL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x97EBAACBL, 0x95BD, 0x11D0, {0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("97EBAACB-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_QUALITY); #define KSCATEGORY_QUALITY DEFINE_GUIDNAMED(KSCATEGORY_QUALITY) @@ -308,7 +308,7 @@ typedef enum } KSINTERFACE_STANDARD; #define STATIC_KSINTERFACESETID_FileIo \ - 0x8C6F932CL, 0xE771, 0x11D0, 0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x8C6F932CL, 0xE771, 0x11D0, {0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("8C6F932C-E771-11D0-B8FF-00A0C9223196", KSINTERFACESETID_FileIo); #define KSINTERFACESETID_FileIo DEFINE_GUIDNAMED(KSINTERFACESETID_FileIo) @@ -337,7 +337,7 @@ DEFINE_GUIDSTRUCT("4747B320-62CE-11CF-A5D6-28DB04C10000", KSMEDIUMSETID_Standard */ #define STATIC_KSPROPSETID_Clock \ - 0xDF12A4C0L, 0xAC17, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("DF12A4C0-AC17-11CF-A5D6-28DB04C10000", KSPROPSETID_Clock); #define KSPROPSETID_Clock DEFINE_GUIDNAMED(KSPROPSETID_Clock) @@ -355,7 +355,7 @@ typedef enum } KSPROPERTY_CLOCK; #define STATIC_KSEVENTSETID_Clock \ - 0x364D8E20L, 0x62C7, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x364D8E20L, 0x62C7, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("364D8E20-62C7-11CF-A5D6-28DB04C10000", KSEVENTSETID_Clock); #define KSEVENTSETID_Clock DEFINE_GUIDNAMED(KSEVENTSETID_Clock) @@ -491,7 +491,7 @@ typedef enum */ #define KSPROPSETID_GM \ - 0xAF627536L, 0xE719, 0x11D2, 0x8A, 0x1D, 0x00, 0x60, 0x97, 0xD2, 0xDF, 0x5D + 0xAF627536L, 0xE719, 0x11D2, {0x8A, 0x1D, 0x00, 0x60, 0x97, 0xD2, 0xDF, 0x5D} typedef enum { @@ -508,7 +508,7 @@ typedef enum */ #define STATIC_KSPROPSETID_MediaSeeking\ - 0xEE904F0CL, 0xD09B, 0x11D0, 0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0xEE904F0CL, 0xD09B, 0x11D0, {0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("EE904F0C-D09B-11D0-ABE9-00A0C9223196", KSPROPSETID_MediaSeeking); #define KSPROPSETID_MediaSeeking DEFINE_GUIDNAMED(KSPROPSETID_MediaSeeking) @@ -652,12 +652,12 @@ typedef struct { */ #define STATIC_KSPROPSETID_Pin\ - 0x8C134960L, 0x51AD, 0x11CF, 0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00 + 0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("8C134960-51AD-11CF-878A-94F801C10000", KSPROPSETID_Pin); #define KSPROPSETID_Pin DEFINE_GUIDNAMED(KSPROPSETID_Pin) #define STATIC_KSNAME_Pin\ - 0x146F1A80L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x146F1A80L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("146F1A80-4791-11D0-A5D6-28DB04C10000", KSNAME_Pin); #define KSNAME_Pin DEFINE_GUIDNAMED(KSNAME_Pin) @@ -725,7 +725,7 @@ typedef enum */ #define STATIC_KSPROPSETID_Stream\ - 0x65aaba60L, 0x98ae, 0x11cf, 0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} DEFINE_GUIDSTRUCT("65aaba60-98ae-11cf-a10d-0020afd156e4", KSPROPSETID_Stream); #define KSPROPSETID_Stream DEFINE_GUIDNAMED(KSPROPSETID_Stream) @@ -844,7 +844,7 @@ typedef enum */ #define STATIC_KSPROPSETID_StreamAllocator\ - 0xcf6e4342L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0xcf6e4342L, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} DEFINE_GUIDSTRUCT("cf6e4342-ec87-11cf-a130-0020afd156e4", KSPROPSETID_StreamAllocator); #define KSPROPSETID_StreamAllocator DEFINE_GUIDNAMED(KSPROPSETID_StreamAllocator) @@ -855,7 +855,7 @@ typedef enum } KSPROPERTY_STREAMALLOCATOR; #define KSMETHODSETID_StreamAllocator \ - 0xcf6e4341L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0xcf6e4341L, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} typedef enum { @@ -893,7 +893,7 @@ typedef enum */ #define STATIC_KSPROPSETID_Topology\ - 0x720D4AC0L, 0x7533, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 + 0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00} DEFINE_GUIDSTRUCT("720D4AC0-7533-11D0-A5D6-28DB04C10000", KSPROPSETID_Topology); #define KSPROPSETID_Topology DEFINE_GUIDNAMED(KSPROPSETID_Topology) @@ -1243,7 +1243,7 @@ typedef PVOID KSDEVICE_HEADER, */ #define STATIC_KSDATAFORMAT_SPECIFIER_NONE\ - 0x0F6417D6L, 0xC318, 0x11D0, 0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + 0x0F6417D6L, 0xC318, 0x11D0, {0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} DEFINE_GUIDSTRUCT("0F6417D6-C318-11D0-A43F-00A0C9223196", KSDATAFORMAT_SPECIFIER_NONE); #define KSDATAFORMAT_SPECIFIER_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_NONE) diff --git a/include/psdk/ksmedia.h b/include/psdk/ksmedia.h index a1b1c0c314e..32e5e3e5269 100644 --- a/include/psdk/ksmedia.h +++ b/include/psdk/ksmedia.h @@ -28,7 +28,7 @@ DEFINE_GUIDSTRUCT("FBF6F530-07B9-11D2-A71E-0000F8004788", KSCATEGORY_AUDIO_DEVIC /* video */ #define STATIC_PINNAME_VIDEO_CAPTURE \ - 0xfb6c4281, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba + 0xfb6c4281, 0x353, 0x11d1, {0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba} #define STATIC_PINNAME_CAPTURE STATIC_PINNAME_VIDEO_CAPTURE DEFINE_GUIDSTRUCT("FB6C4281-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_CAPTURE); #define PINNAME_VIDEO_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_CAPTURE) @@ -130,32 +130,32 @@ DEFINE_GUIDSTRUCT("9EA331FA-B91B-45F8-9285-BD2BC77AFCDE", KSCATEGORY_AUDIO_SPLIT */ #define STATIC_KSNODETYPE_ADC\ - 0x4D837FE0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("4D837FE0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_ADC); #define KSNODETYPE_ADC DEFINE_GUIDNAMED(KSNODETYPE_ADC) #define STATIC_KSNODETYPE_AGC\ - 0xE88C9BA0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xE88C9BA0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("E88C9BA0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_AGC); #define KSNODETYPE_AGC DEFINE_GUIDNAMED(KSNODETYPE_AGC) #define STATIC_KSNODETYPE_3D_EFFECTS\ - 0x55515860L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x55515860L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("55515860-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_3D_EFFECTS); #define KSNODETYPE_3D_EFFECTS DEFINE_GUIDNAMED(KSNODETYPE_3D_EFFECTS) #define STATIC_KSNODETYPE_SUPERMIX\ - 0xE573ADC0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xE573ADC0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("E573ADC0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUPERMIX); #define KSNODETYPE_SUPERMIX DEFINE_GUIDNAMED(KSNODETYPE_SUPERMIX) #define STATIC_KSNODETYPE_SRC\ - 0x9DB7B9E0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x9DB7B9E0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("9DB7B9E0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SRC); #define KSNODETYPE_SRC DEFINE_GUIDNAMED(KSNODETYPE_SRC) #define STATIC_KSNODETYPE_DAC\ - 0x507AE360L, 0xC554, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("507AE360-C554-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DAC); #define KSNODETYPE_DAC DEFINE_GUIDNAMED(KSNODETYPE_DAC) @@ -175,12 +175,12 @@ DEFINE_GUIDSTRUCT("DFF220E3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_CD_PLAYER); #define KSNODETYPE_CD_PLAYER DEFINE_GUIDNAMED(KSNODETYPE_CD_PLAYER) #define STATIC_KSNODETYPE_CHORUS\ - 0x20173F20L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x20173F20L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("20173F20-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_CHORUS); #define KSNODETYPE_CHORUS DEFINE_GUIDNAMED(KSNODETYPE_CHORUS) #define STATIC_KSNODETYPE_REVERB\ - 0xEF0328E0L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xEF0328E0L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("EF0328E0-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_REVERB); #define KSNODETYPE_REVERB DEFINE_GUIDNAMED(KSNODETYPE_REVERB) @@ -201,127 +201,127 @@ DEFINE_GUIDSTRUCT("DFF21CE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPEAKER); #define KSNODETYPE_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_SPEAKER) #define STATIC_KSAUDFNAME_RECORDING_CONTROL\ - 0x185FEDFAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDFAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDFA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_CONTROL); #define KSAUDFNAME_RECORDING_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_CONTROL) #define STATIC_KSNODETYPE_VOLUME\ - 0x3A5ACC00L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x3A5ACC00L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("3A5ACC00-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_VOLUME); #define KSNODETYPE_VOLUME DEFINE_GUIDNAMED(KSNODETYPE_VOLUME) #define STATIC_KSAUDFNAME_WAVE_VOLUME\ - 0x185FEDE5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_VOLUME); #define KSAUDFNAME_WAVE_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_VOLUME) #define STATIC_KSNODETYPE_MUTE\ - 0x02B223C0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x02B223C0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("02B223C0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUTE); #define KSNODETYPE_MUTE DEFINE_GUIDNAMED(KSNODETYPE_MUTE) #define STATIC_KSAUDFNAME_WAVE_MUTE\ - 0x185FEDE6L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE6L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE6-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_MUTE); #define KSAUDFNAME_WAVE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_MUTE) #define STATIC_KSAUDFNAME_MIC_VOLUME\ - 0x185FEDEDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDED-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_VOLUME); #define KSAUDFNAME_MIC_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_VOLUME) #define STATIC_KSNODETYPE_SUM\ - 0xDA441A60L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xDA441A60L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("DA441A60-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUM); #define KSNODETYPE_SUM DEFINE_GUIDNAMED(KSNODETYPE_SUM) #define STATIC_KSAUDFNAME_MASTER_VOLUME\ - 0x185FEDE3L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE3L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE3-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_VOLUME); #define KSAUDFNAME_MASTER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_VOLUME) #define STATIC_KSAUDFNAME_CD_VOLUME\ - 0x185FEDE9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE9L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_VOLUME); #define KSAUDFNAME_CD_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_CD_VOLUME) #define STATIC_KSAUDFNAME_RECORDING_SOURCE\ - 0x185FEDEFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEFL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_SOURCE); #define KSAUDFNAME_RECORDING_SOURCE DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_SOURCE) #define STATIC_KSAUDFNAME_LINE_IN_VOLUME\ - 0x185FEDF4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDF4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDF4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN_VOLUME); #define KSAUDFNAME_LINE_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN_VOLUME) #define STATIC_KSAUDFNAME_AUX_VOLUME\ - 0x185FEDFCL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDFCL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDFC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_VOLUME); #define KSAUDFNAME_AUX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_AUX_VOLUME) #define STATIC_KSAUDFNAME_MIC_IN_VOLUME\ - 0x185FEDF5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDF5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDF5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_IN_VOLUME); #define KSAUDFNAME_MIC_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_IN_VOLUME) #define STATIC_KSNODETYPE_LOUDNESS\ - 0x41887440L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x41887440L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("41887440-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_LOUDNESS); #define KSNODETYPE_LOUDNESS DEFINE_GUIDNAMED(KSNODETYPE_LOUDNESS) #define STATIC_KSAUDFNAME_MICROPHONE_BOOST\ - 0x2bc31d6aL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 + 0x2bc31d6aL, 0x96e3, 0x11d2, {0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68} DEFINE_GUIDSTRUCT("2BC31D6A-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MICROPHONE_BOOST); #define KSAUDFNAME_MICROPHONE_BOOST DEFINE_GUIDNAMED(KSAUDFNAME_MICROPHONE_BOOST) #define STATIC_KSAUDFNAME_CD_MUTE\ - 0x185FEDEAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_MUTE); #define KSAUDFNAME_CD_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_CD_MUTE) #define STATIC_KSAUDFNAME_LINE_MUTE\ - 0x185FEDECL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDECL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_MUTE); #define KSAUDFNAME_LINE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_LINE_MUTE) #define STATIC_KSAUDFNAME_MIC_MUTE\ - 0x185FEDEEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDEEL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDEE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_MUTE); #define KSAUDFNAME_MIC_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MIC_MUTE) #define STATIC_KSAUDFNAME_AUX_MUTE\ - 0x185FEDFDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDFDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDFD-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_MUTE); #define KSAUDFNAME_AUX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_AUX_MUTE) #define STATIC_KSAUDFNAME_VOLUME_CONTROL\ - 0x185FEDF7L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDF7L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDF7-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_VOLUME_CONTROL); #define KSAUDFNAME_VOLUME_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_VOLUME_CONTROL) #define STATIC_KSNODETYPE_MUX\ - 0x2CEAF780L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x2CEAF780L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("2CEAF780-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUX); #define KSNODETYPE_MUX DEFINE_GUIDNAMED(KSNODETYPE_MUX) #define STATIC_KSAUDFNAME_MASTER_MUTE\ - 0x185FEDE4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0x185FEDE4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("185FEDE4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_MUTE); #define KSAUDFNAME_MASTER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_MUTE) #define STATIC_KSNODETYPE_PEAKMETER\ - 0xa085651eL, 0x5f0d, 0x4b36, 0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e + 0xa085651eL, 0x5f0d, 0x4b36, {0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e} DEFINE_GUIDSTRUCT("A085651E-5F0D-4b36-A869-D195D6AB4B9E", KSNODETYPE_PEAKMETER); #define KSNODETYPE_PEAKMETER DEFINE_GUIDNAMED(KSNODETYPE_PEAKMETER) #define STATIC_KSNODETYPE_STEREO_WIDE\ - 0xA9E69800L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0xA9E69800L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("A9E69800-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_STEREO_WIDE); #define KSNODETYPE_STEREO_WIDE DEFINE_GUIDNAMED(KSNODETYPE_STEREO_WIDE) #define STATIC_KSNODETYPE_TONE\ - 0x7607E580L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 + 0x7607E580L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1} DEFINE_GUIDSTRUCT("7607E580-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_TONE); #define KSNODETYPE_TONE DEFINE_GUIDNAMED(KSNODETYPE_TONE) @@ -375,11 +375,11 @@ typedef struct { } KSDATARANGE_AUDIO, *PKSDATARANGE_AUDIO; #if !defined( DEFINE_WAVEFORMATEX_GUID ) -#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #endif #define STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX\ - 0x00000000L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + 0x00000000L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} DEFINE_GUIDSTRUCT("00000000-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_WAVEFORMATEX); #define KSDATAFORMAT_SUBTYPE_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) @@ -403,12 +403,12 @@ DEFINE_GUIDSTRUCT("73647561-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_AUDI #define KSDATAFORMAT_TYPE_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUDIO) #define STATIC_KSDATAFORMAT_SPECIFIER_DSOUND\ - 0x518590a2L, 0xa184, 0x11d0, 0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 + 0x518590a2L, 0xa184, 0x11d0, {0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3} DEFINE_GUIDSTRUCT("518590a2-a184-11d0-8522-00c04fd9baf3", KSDATAFORMAT_SPECIFIER_DSOUND); #define KSDATAFORMAT_SPECIFIER_DSOUND DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DSOUND) #define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG\ - 0x6dba3190L, 0x67bd, 0x11cf, 0xa0, 0xf7, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 + 0x6dba3190L, 0x67bd, 0x11cf, {0xa0, 0xf7, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4} DEFINE_GUIDSTRUCT("6dba3190-67bd-11cf-a0f7-0020afd156e4", KSDATAFORMAT_SUBTYPE_ANALOG); #define KSDATAFORMAT_SUBTYPE_ANALOG DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ANALOG) @@ -446,22 +446,22 @@ DEFINE_GUIDSTRUCT("00000003-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_I #define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) #define STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\ - 0x05589f81L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a + 0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a} DEFINE_GUIDSTRUCT("05589f81-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_WAVEFORMATEX); #define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) #define STATIC_KSDATAFORMAT_SUBTYPE_AC3_AUDIO\ - 0xe06d802cL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea + 0xe06d802cL, 0xdb46, 0x11cf, {0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea} DEFINE_GUIDSTRUCT("e06d802c-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_AC3_AUDIO); #define KSDATAFORMAT_SUBTYPE_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) #define STATIC_KSDATAFORMAT_SPECIFIER_AC3_AUDIO\ - 0xe06d80e4L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea + 0xe06d80e4L, 0xdb46, 0x11cf, {0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea} DEFINE_GUIDSTRUCT("e06d80e4-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_AC3_AUDIO); #define KSDATAFORMAT_SPECIFIER_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_AC3_AUDIO) #define STATIC_KSPROPSETID_AC3\ - 0xBFABE720L, 0x6E1F, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 + 0xBFABE720L, 0x6E1F, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} DEFINE_GUIDSTRUCT("BFABE720-6E1F-11D0-BCF2-444553540000", KSPROPSETID_AC3); #define KSPROPSETID_AC3 DEFINE_GUIDNAMED(KSPROPSETID_AC3) @@ -532,7 +532,7 @@ typedef enum { } KSPROPERTY_AUDIO; #define STATIC_KSEVENTSETID_AudioControlChange\ - 0xE85E9698L, 0xFA2F, 0x11D1, 0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 + 0xE85E9698L, 0xFA2F, 0x11D1, {0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3} DEFINE_GUIDSTRUCT("E85E9698-FA2F-11D1-95BD-00C04FB925D3", KSEVENTSETID_AudioControlChange); #define KSEVENTSETID_AudioControlChange DEFINE_GUIDNAMED(KSEVENTSETID_AudioControlChange) @@ -542,7 +542,7 @@ typedef enum { #define STATIC_KSEVENTSETID_LoopedStreaming\ - 0x4682B940L, 0xC6EF, 0x11D0, 0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D + 0x4682B940L, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D} DEFINE_GUIDSTRUCT("4682B940-C6EF-11D0-96D8-00AA0051E51D", KSEVENTSETID_LoopedStreaming); #define KSEVENTSETID_LoopedStreaming DEFINE_GUIDNAMED(KSEVENTSETID_LoopedStreaming) @@ -551,7 +551,7 @@ typedef enum { } KSEVENT_LOOPEDSTREAMING; #define STATIC_KSEVENTSETID_Connection\ - 0x7f4bcbe0L, 0x9ea5, 0x11cf, 0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00 + 0x7f4bcbe0L, 0x9ea5, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00} DEFINE_GUIDSTRUCT("7f4bcbe0-9ea5-11cf-a5d6-28db04c10000", KSEVENTSETID_Connection); #define KSEVENTSETID_Connection DEFINE_GUIDNAMED(KSEVENTSETID_Connection) diff --git a/include/psdk/msxml2.idl b/include/psdk/msxml2.idl index 89914004955..f2841a5f3f2 100644 --- a/include/psdk/msxml2.idl +++ b/include/psdk/msxml2.idl @@ -85,6 +85,22 @@ interface IMXAttributes; interface IMXReaderControl; interface IMXWriter; +interface IXMLDOMSchemaCollection2; +interface ISchemaStringCollection; +interface ISchemaItemCollection; +interface ISchemaItem; +interface ISchema; +interface ISchemaParticle; +interface ISchemaAttribute; +interface ISchemaElement; +interface ISchemaType; +interface ISchemaComplexType; +interface ISchemaAttributeGroup; +interface ISchemaModelGroup; +interface ISchemaAny; +interface ISchemaIdentityConstraint; +interface ISchemaNotation; + cpp_quote("#define DOMDocument DOMDocument2") cpp_quote("#define CLSID_DOMDocument CLSID_DOMDocument2") @@ -108,6 +124,134 @@ typedef enum tagDOMNodeType } DOMNodeType; cpp_quote("#endif /* __WIDL_XMLDOM_H */") +typedef enum _SOMITEMTYPE +{ + SOMITEM_SCHEMA = 0x1000, + SOMITEM_ATTRIBUTE = 0x1001, + SOMITEM_ATTRIBUTEGROUP = 0x1002, + SOMITEM_NOTATION = 0x1003, + SOMITEM_IDENTITYCONSTRAINT = 0x1100, + SOMITEM_KEY = 0x1101, + SOMITEM_KEYREF = 0x1102, + SOMITEM_UNIQUE = 0x1103, + SOMITEM_ANYTYPE = 0x2000, + SOMITEM_DATATYPE = 0x2100, + SOMITEM_DATATYPE_ANYTYPE = 0x2101, + SOMITEM_DATATYPE_ANYURI = 0x2102, + SOMITEM_DATATYPE_BASE64BINARY = 0x2103, + SOMITEM_DATATYPE_BOOLEAN = 0x2104, + SOMITEM_DATATYPE_BYTE = 0x2105, + SOMITEM_DATATYPE_DATE = 0x2106, + SOMITEM_DATATYPE_DATETIME = 0x2107, + SOMITEM_DATATYPE_DAY = 0x2108, + SOMITEM_DATATYPE_DECIMAL = 0x2109, + SOMITEM_DATATYPE_DOUBLE = 0x210A, + SOMITEM_DATATYPE_DURATION = 0x210B, + SOMITEM_DATATYPE_ENTITIES = 0x210C, + SOMITEM_DATATYPE_ENTITY = 0x210D, + SOMITEM_DATATYPE_FLOAT = 0x210E, + SOMITEM_DATATYPE_HEXBINARY = 0x210F, + SOMITEM_DATATYPE_ID = 0x2110, + SOMITEM_DATATYPE_IDREF = 0x2111, + SOMITEM_DATATYPE_IDREFS = 0x2112, + SOMITEM_DATATYPE_INT = 0x2113, + SOMITEM_DATATYPE_INTEGER = 0x2114, + SOMITEM_DATATYPE_LANGUAGE = 0x2115, + SOMITEM_DATATYPE_LONG = 0x2116, + SOMITEM_DATATYPE_MONTH = 0x2117, + SOMITEM_DATATYPE_MONTHDAY = 0x2118, + SOMITEM_DATATYPE_NAME = 0x2119, + SOMITEM_DATATYPE_NCNAME = 0x211A, + SOMITEM_DATATYPE_NEGATIVEINTEGER = 0x211B, + SOMITEM_DATATYPE_NMTOKEN = 0x211C, + SOMITEM_DATATYPE_NMTOKENS = 0x211D, + SOMITEM_DATATYPE_NONNEGATIVEINTEGER = 0x211E, + SOMITEM_DATATYPE_NONPOSITIVEINTEGER = 0x211F, + SOMITEM_DATATYPE_NORMALIZEDSTRING = 0x2120, + SOMITEM_DATATYPE_NOTATION = 0x2121, + SOMITEM_DATATYPE_POSITIVEINTEGER = 0x2122, + SOMITEM_DATATYPE_QNAME = 0x2123, + SOMITEM_DATATYPE_SHORT = 0x2124, + SOMITEM_DATATYPE_STRING = 0x2125, + SOMITEM_DATATYPE_TIME = 0x2126, + SOMITEM_DATATYPE_TOKEN = 0x2127, + SOMITEM_DATATYPE_UNSIGNEDBYTE = 0x2128, + SOMITEM_DATATYPE_UNSIGNEDINT = 0x2129, + SOMITEM_DATATYPE_UNSIGNEDLONG = 0x212A, + SOMITEM_DATATYPE_UNSIGNEDSHORT = 0x212B, + SOMITEM_DATATYPE_YEAR = 0x212C, + SOMITEM_DATATYPE_YEARMONTH = 0x212D, + SOMITEM_DATATYPE_ANYSIMPLETYPE = 0x21FF, + SOMITEM_SIMPLETYPE = 0x2200, + SOMITEM_COMPLEXTYPE = 0x2400, + SOMITEM_PARTICLE = 0x4000, + SOMITEM_ANY = 0x4001, + SOMITEM_ANYATTRIBUTE = 0x4002, + SOMITEM_ELEMENT = 0x4003, + SOMITEM_GROUP = 0x4100, + SOMITEM_ALL = 0x4101, + SOMITEM_CHOICE = 0x4102, + SOMITEM_SEQUENCE = 0x4103, + SOMITEM_EMPTYPARTICLE = 0x4104, + SOMITEM_NULL = 0x0800, + SOMITEM_NULL_TYPE = 0x2800, + SOMITEM_NULL_ANY = 0x4801, + SOMITEM_NULL_ANYATTRIBUTE = 0x4802, + SOMITEM_NULL_ELEMENT = 0x4803, +} SOMITEMTYPE; + +typedef enum _SCHEMAUSE +{ + SCHEMAUSE_OPTIONAL, + SCHEMAUSE_PROHIBITED, + SCHEMAUSE_REQUIRED, +} SCHEMAUSE; + +typedef enum _SCHEMADERIVATIONMETHOD +{ + SCHEMADERIVATIONMETHOD_EMPTY = 0x0000, + SCHEMADERIVATIONMETHOD_SUBSTITUTION = 0x0001, + SCHEMADERIVATIONMETHOD_EXTENSION = 0x0002, + SCHEMADERIVATIONMETHOD_RESTRICTION = 0x0004, + SCHEMADERIVATIONMETHOD_LIST = 0x0008, + SCHEMADERIVATIONMETHOD_UNION = 0x0010, + SCHEMADERIVATIONMETHOD_ALL = 0x00FF, + SCHEMADERIVATIONMETHOD_NONE = 0x0100, +} SCHEMADERIVATIONMETHOD; + +typedef enum _SCHEMACONTENTTYPE +{ + SCHEMACONTENTTYPE_EMPTY, + SCHEMACONTENTTYPE_TEXTONLY, + SCHEMACONTENTTYPE_ELEMENTONLY, + SCHEMACONTENTTYPE_MIXED, +} SCHEMACONTENTTYPE; + +typedef enum _SCHEMAPROCESSCONTENTS +{ + SCHEMAPROCESSCONTENTS_NONE, + SCHEMAPROCESSCONTENTS_SKIP, + SCHEMAPROCESSCONTENTS_LAX, + SCHEMAPROCESSCONTENTS_STRICT, +} SCHEMAPROCESSCONTENTS; + +typedef enum _SCHEMAWHITESPACE +{ + SCHEMAWHITESPACE_NONE = -1, + SCHEMAWHITESPACE_PRESERVE = 0, + SCHEMAWHITESPACE_REPLACE = 1, + SCHEMAWHITESPACE_COLLAPSE = 2, +} SCHEMAWHITESPACE; + + +typedef enum _SCHEMATYPEVARIETY +{ + SCHEMATYPEVARIETY_NONE = -1, + SCHEMATYPEVARIETY_ATOMIC = 0, + SCHEMATYPEVARIETY_LIST = 1, + SCHEMATYPEVARIETY_UNION = 2, +} SCHEMATYPEVARIETY; + [ local, object, @@ -417,6 +561,35 @@ interface IXMLDOMSchemaCollection : IDispatch HRESULT _newEnum([retval, out] IUnknown **ppUnk); } +[ + local, + object, + uuid(50ea08b0-dd1b-4664-9a50-c2f40f4bd79a), +] +interface IXMLDOMSchemaCollection2 : IXMLDOMSchemaCollection +{ + [id(DISPID_SOM_VALIDATE)] + HRESULT validate(); + + [propput, id(DISPID_SOM_VALIDATEONLOAD)] + HRESULT validateOnLoad( + [in] VARIANT_BOOL validateOnLoad); + + [propget, id(DISPID_SOM_VALIDATEONLOAD)] + HRESULT validateOnLoad( + [out,retval] VARIANT_BOOL* validateOnLoad); + + [id(DISPID_SOM_GETSCHEMA)] + HRESULT getSchema( + [in] BSTR namespaceURI, + [out,retval] ISchema** schema); + + [id(DISPID_SOM_GETDECLARATION)] + HRESULT getDeclaration( + [in] IXMLDOMNode* node, + [out,retval]ISchemaItem** item); +}; + [ local, object, @@ -1106,6 +1279,15 @@ coclass FreeThreadedDOMDocument30 [default, source] dispinterface XMLDOMDocumentEvents; } +[ + uuid(88d969c1-f192-11d4-a65f-0040963251e5), +] +coclass FreeThreadedDOMDocument40 +{ + [default] interface IXMLDOMDocument2; + [default, source] dispinterface XMLDOMDocumentEvents; +}; + [ uuid(373984c9-b845-449b-91e7-45ac83036ade) ] @@ -1130,6 +1312,14 @@ coclass XMLSchemaCache30 [default] interface IXMLDOMSchemaCollection; } +[ + uuid(88d969c2-f192-11d4-a65f-0040963251e5) +] +coclass XMLSchemaCache40 +{ + [default] interface IXMLDOMSchemaCollection2; +}; + [ uuid(2933BF94-7B36-11d2-B20E-00C04F983E60) ] @@ -1959,6 +2149,443 @@ interface IMXWriter : IDispatch HRESULT flush(); }; +[ + local, + object, + uuid(50ea08b1-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaStringCollection : IDispatch +{ + [id(DISPID_VALUE), propget] + HRESULT item( + [in] long index, + [out,retval] BSTR* bstr); + + [id(DISPID_SOM_LENGTH), propget] + HRESULT length( + [out,retval] long* length); + + [id(DISPID_NEWENUM), hidden, restricted, propget] + HRESULT _newEnum( + [out,retval] IUnknown** ppunk); +}; + +[ + local, + object, + uuid(50ea08b2-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaItemCollection : IDispatch +{ + [id(DISPID_VALUE), propget] + HRESULT item( + [in] long index, + [out,retval]ISchemaItem** item); + + [id(DISPID_SOM_ITEMBYNAME)] + HRESULT itemByName( + [in] BSTR name, + [out,retval] ISchemaItem** item); + + [id(DISPID_SOM_ITEMBYQNAME)] + HRESULT itemByQName( + [in] BSTR name, + [in] BSTR namespaceURI, + [out,retval] ISchemaItem** item); + + [id(DISPID_SOM_LENGTH), propget] + HRESULT length( + [out,retval]long* length); + + [id(DISPID_NEWENUM), hidden, restricted, propget] + HRESULT _newEnum( + [out,retval]IUnknown** ppunk); +}; + +[ + local, + object, + uuid(50ea08b3-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaItem : IDispatch +{ + [id(DISPID_SOM_NAME), propget] + HRESULT name( + [out,retval] BSTR* name); + + [id(DISPID_SOM_NAMESPACEURI), propget] + HRESULT namespaceURI( + [out,retval] BSTR* namespaceURI); + + [id(DISPID_SOM_SCHEMA), propget] + HRESULT schema( + [out,retval] ISchema** schema); + + [id(DISPID_SOM_ID), propget] + HRESULT id( + [out,retval] BSTR* id); + + [id(DISPID_SOM_ITEMTYPE), propget] + HRESULT itemType( + [out,retval] SOMITEMTYPE* itemType); + + [id(DISPID_SOM_UNHANDLEDATTRS), propget] + HRESULT unhandledAttributes( + [out,retval] IVBSAXAttributes** attributes); + + [id(DISPID_SOM_WRITEANNOTATION)] + HRESULT writeAnnotation( + [in] IUnknown* annotationSink, + [out,retval] VARIANT_BOOL* isWritten); +}; + +[ + local, + object, + uuid(50ea08b4-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchema : ISchemaItem +{ + [id(DISPID_SOM_TARGETNAMESPACE), propget] + HRESULT targetNamespace( + [out,retval] BSTR* targetNamespace); + + [id(DISPID_SOM_VERSION), propget] + HRESULT version( + [out,retval] BSTR* version); + + [id(DISPID_SOM_TYPES), propget] + HRESULT types( + [out,retval] ISchemaItemCollection** types); + + [id(DISPID_SOM_ELEMENTS), propget] + HRESULT elements( + [out,retval] ISchemaItemCollection** elements); + + [id(DISPID_SOM_ATTRIBUTES), propget] + HRESULT attributes( + [out,retval] ISchemaItemCollection** attributes); + + [id(DISPID_SOM_ATTRIBUTEGROUPS), propget] + HRESULT attributeGroups( + [out,retval] ISchemaItemCollection** attributeGroups); + + [id(DISPID_SOM_MODELGROUPS), propget] + HRESULT modelGroups( + [out,retval] ISchemaItemCollection** modelGroups); + + [id(DISPID_SOM_NOTATIONS), propget] + HRESULT notations( + [out,retval] ISchemaItemCollection** notations); + + [id(DISPID_SOM_SCHEMALOCATIONS), propget] + HRESULT schemaLocations( + [out,retval] ISchemaStringCollection** schemaLocations); +}; + +[ + local, + object, + uuid(50ea08b5-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaParticle : ISchemaItem +{ + [id(DISPID_SOM_MINOCCURS), propget] + HRESULT minOccurs( + [out,retval] VARIANT* minOccurs); + + [id(DISPID_SOM_MAXOCCURS), propget] + HRESULT maxOccurs( + [out,retval] VARIANT* maxOccurs); +}; + +[ + object, + uuid(50ea08b6-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaAttribute : ISchemaItem +{ + [id(DISPID_SOM_TYPE), propget] + HRESULT type( + [out,retval] ISchemaType** type); + + [id(DISPID_SOM_SCOPE), propget] + HRESULT scope( + [out,retval] ISchemaComplexType** scope); + + [id(DISPID_SOM_DEFAULTVALUE), propget] + HRESULT defaultValue( + [out,retval]BSTR* defaultValue); + + [id(DISPID_SOM_FIXEDVALUE), propget] + HRESULT fixedValue( + [out,retval] BSTR* fixedValue); + + [id(DISPID_SOM_USE), propget] + HRESULT use( + [out,retval] SCHEMAUSE* use); + + [id(DISPID_SOM_ISREFERENCE), propget] + HRESULT isReference( + [out,retval] VARIANT_BOOL* reference); +}; + +[ + local, + object, + uuid(50ea08b7-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaElement : ISchemaParticle +{ + [id(DISPID_SOM_TYPE), propget] + HRESULT type( + [out,retval] ISchemaType** type); + + [id(DISPID_SOM_SCOPE), propget] + HRESULT scope( + [out,retval] ISchemaComplexType** scope); + + [id(DISPID_SOM_DEFAULTVALUE), propget] + HRESULT defaultValue( + [out,retval] BSTR* defaultValue); + + [id(DISPID_SOM_FIXEDVALUE), propget] + HRESULT fixedValue( + [out,retval] BSTR* fixedValue); + + [id(DISPID_SOM_ISNILLABLE), propget] + HRESULT isNillable( + [out,retval] VARIANT_BOOL* nillable); + + [id(DISPID_SOM_IDCONSTRAINTS), propget] + HRESULT identityConstraints( + [out,retval] ISchemaItemCollection** constraints); + + [id(DISPID_SOM_SUBSTITUTIONGROUP), propget] + HRESULT substitutionGroup( + [out,retval] ISchemaElement** element); + + [id(DISPID_SOM_EXCLUSIONS), propget] + HRESULT substitutionGroupExclusions( + [out,retval] SCHEMADERIVATIONMETHOD* exclusions); + + [id(DISPID_SOM_DISALLOWED), propget] + HRESULT disallowedSubstitutions( + [out,retval] SCHEMADERIVATIONMETHOD* disallowed); + + [id(DISPID_SOM_ISABSTRACT), propget] + HRESULT isAbstract( + [out,retval] VARIANT_BOOL* abstract); + + [id(DISPID_SOM_ISREFERENCE), propget] + HRESULT isReference( + [out,retval] VARIANT_BOOL* reference); +}; + +[ + local, + object, + uuid(50ea08b8-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaType : ISchemaItem +{ + [id(DISPID_SOM_BASETYPES), propget] + HRESULT baseTypes( + [out,retval] ISchemaItemCollection** baseTypes); + + [id(DISPID_SOM_FINAL), propget] + HRESULT final( + [out,retval] SCHEMADERIVATIONMETHOD* final); + + [id(DISPID_SOM_VARIETY), propget] + HRESULT variety( + [out,retval] SCHEMATYPEVARIETY* variety); + + [id(DISPID_SOM_DERIVEDBY), propget] + HRESULT derivedBy( + [out,retval] SCHEMADERIVATIONMETHOD* derivedBy); + + [id(DISPID_SOM_ISVALID)] + HRESULT isValid( + [in] BSTR data, + [out,retval] VARIANT_BOOL* valid); + + [id(DISPID_SOM_MINEXCLUSIVE), propget] + HRESULT minExclusive( + [out,retval]BSTR* minExclusive); + + [id(DISPID_SOM_MININCLUSIVE), propget] + HRESULT minInclusive( + [out,retval] BSTR* minInclusive); + + [id(DISPID_SOM_MAXEXCLUSIVE), propget] + HRESULT maxExclusive( + [out,retval] BSTR* maxExclusive); + + [id(DISPID_SOM_MAXINCLUSIVE), propget] + HRESULT maxInclusive( + [out,retval] BSTR* maxInclusive); + + [id(DISPID_SOM_TOTALDIGITS), propget] + HRESULT totalDigits( + [out,retval] VARIANT* totalDigits); + + [id(DISPID_SOM_FRACTIONDIGITS), propget] + HRESULT fractionDigits( + [out,retval] VARIANT* fractionDigits); + + [id(DISPID_SOM_LENGTH), propget] + HRESULT length( + [out,retval] VARIANT* length); + + [id(DISPID_SOM_MINLENGTH), propget] + HRESULT minLength( + [out,retval]VARIANT* minLength); + + [id(DISPID_SOM_MAXLENGTH), propget] + HRESULT maxLength( + [out,retval]VARIANT* maxLength); + + [id(DISPID_SOM_ENUMERATION), propget] + HRESULT enumeration( + [out,retval] ISchemaStringCollection** enumeration); + + [id(DISPID_SOM_WHITESPACE), propget] + HRESULT whitespace( + [out,retval]SCHEMAWHITESPACE* whitespace); + + [id(DISPID_SOM_PATTERNS), propget] + HRESULT patterns( + [out,retval] ISchemaStringCollection** patterns); +}; + +[ + local, + object, + uuid(50ea08b9-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaComplexType : ISchemaType +{ + [id(DISPID_SOM_ISABSTRACT), propget] + HRESULT isAbstract( + [out,retval] VARIANT_BOOL* abstract); + + [id(DISPID_SOM_ANYATTRIBUTE), propget] + HRESULT anyAttribute( + [out,retval] ISchemaAny** anyAttribute); + + [id(DISPID_SOM_ATTRIBUTES), propget] + HRESULT attributes( + [out,retval] ISchemaItemCollection** attributes); + + [id(DISPID_SOM_CONTENTTYPE), propget] + HRESULT contentType( + [out,retval] SCHEMACONTENTTYPE* contentType); + + [id(DISPID_SOM_CONTENTMODEL), propget] + HRESULT contentModel( + [out,retval] ISchemaModelGroup** contentModel); + + [id(DISPID_SOM_PROHIBITED), propget] + HRESULT prohibitedSubstitutions( + [out,retval] SCHEMADERIVATIONMETHOD* prohibited); +}; + +[ + local, + object, + uuid(50ea08ba-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaAttributeGroup : ISchemaItem +{ + [id(DISPID_SOM_ANYATTRIBUTE), propget] + HRESULT anyAttribute( + [out,retval] ISchemaAny** anyAttribute); + + [id(DISPID_SOM_ATTRIBUTES), propget] + HRESULT attributes( + [out,retval] ISchemaItemCollection** attributes); +}; + +[ + local, + object, + uuid(50ea08bb-dd1b-4664-9a50-c2f40f4bd79a), + dual, +] +interface ISchemaModelGroup : ISchemaParticle +{ + [id(DISPID_SOM_PARTICLES), propget] + HRESULT particles( + [out,retval] ISchemaItemCollection** particles); +}; + +[ + local, + object, + uuid(50ea08bc-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaAny : ISchemaParticle +{ + [id(DISPID_SOM_NAMESPACES), propget] + HRESULT namespaces( + [out,retval] ISchemaStringCollection** namespaces); + + [id(DISPID_SOM_PROCESSCONTENTS), propget] + HRESULT processContents( + [out,retval] SCHEMAPROCESSCONTENTS* processContents); +}; + +[ + local, + object, + uuid(50ea08bd-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaIdentityConstraint : ISchemaItem +{ + [id(DISPID_SOM_SELECTOR), propget] + HRESULT selector( + [out,retval] BSTR* selector); + + [id(DISPID_SOM_FIELDS), propget] + HRESULT fields( + [out,retval] ISchemaStringCollection** fields); + + [id(DISPID_SOM_REFERENCEDKEY), propget] + HRESULT referencedKey( + [out,retval] ISchemaIdentityConstraint** key); +}; + +[ + local, + object, + uuid(50ea08be-dd1b-4664-9a50-c2f40f4bd79a), + dual +] +interface ISchemaNotation : ISchemaItem +{ + [id(DISPID_SOM_SYSTEMIDENTIFIER), propget] + HRESULT systemIdentifier( + [out,retval] BSTR* uri); + + [id(DISPID_SOM_PUBLICIDENTIFIER), propget] + HRESULT publicIdentifier( + [out,retval] BSTR* uri); +}; + + [ uuid(079aa557-4a18-424a-8eee-e39f0a8d41b9) ] @@ -2028,6 +2655,26 @@ coclass MXXMLWriter30 interface IVBSAXLexicalHandler; }; +[ + uuid(88d969c8-f192-11d4-a65f-0040963251e5), +] +coclass MXXMLWriter40 +{ + [default] interface IMXWriter; + + interface ISAXContentHandler; + interface ISAXDeclHandler; + interface ISAXDTDHandler; + interface ISAXErrorHandler; + interface ISAXLexicalHandler; + + interface IVBSAXContentHandler; + interface IVBSAXDeclHandler; + interface IVBSAXDTDHandler; + interface IVBSAXErrorHandler; + interface IVBSAXLexicalHandler; +}; + [ uuid(4dd441ad-526d-4a77-9f1b-9841ed802fb0) ] @@ -2048,5 +2695,15 @@ coclass SAXAttributes30 interface ISAXAttributes; }; +[ + uuid(88d969ca-f192-11d4-a65f-0040963251e5), +] +coclass SAXAttributes40 +{ + [default] interface IMXAttributes; + interface IVBSAXAttributes; + interface ISAXAttributes; +}; + } /* Library MSXML */ diff --git a/include/psdk/msxml2did.h b/include/psdk/msxml2did.h index f2adaaff427..d7489d0524f 100644 --- a/include/psdk/msxml2did.h +++ b/include/psdk/msxml2did.h @@ -394,5 +394,87 @@ #define DISPID_MX_READER_CONTROL_RESUME 0x00000577 #define DISPID_MX_READER_CONTROL_SUSPEND 0x00000578 +#define DISPID_MX_SCHEMADECLHANDLER 0x0000057a +#define DISPID_MX_SCHEMADECLHANDLER_SCHEMAELEMENTDECL 0x0000057b + +#define DISPID_MX_NSMGR 0x0000057d +#define DISPID_MX_NSMGR_ALLOWOVERRIDE 0x0000057e +#define DISPID_MX_NSMGR_RESET 0x0000057f +#define DISPID_MX_NSMGR_PUSHCONTEXT 0x00000580 +#define DISPID_MX_NSMGR_PUSHNODECONTEXT 0x00000581 +#define DISPID_MX_NSMGR_POPCONTEXT 0x00000582 +#define DISPID_MX_NSMGR_DECLAREPREFIX 0x00000583 +#define DISPID_MX_NSMGR_GETDECLAREDPREFIXES 0x00000584 +#define DISPID_MX_NSMGR_GETPREFIXES 0x00000585 +#define DISPID_MX_NSMGR_GETURI 0x00000586 +#define DISPID_MX_NSMGR_GETURIFROMNODE 0x00000587 +#define DISPID_MX_NSMGR_LENGTH 0x00000588 + +#define DISPID_SOM_VALIDATE 0x0000058b +#define DISPID_SOM_VALIDATEONLOAD 0x0000058c +#define DISPID_SOM_GETSCHEMA 0x0000058d +#define DISPID_SOM_GETDECLARATION 0x0000058e +#define DISPID_SOM_ITEMBYNAME 0x0000058f +#define DISPID_SOM_ITEMBYQNAME 0x00000590 +#define DISPID_SOM_ANYATTRIBUTE 0x00000591 +#define DISPID_SOM_ATTRIBUTEGROUPS 0x00000592 +#define DISPID_SOM_ATTRIBUTES 0x00000593 +#define DISPID_SOM_BASETYPES 0x00000594 +#define DISPID_SOM_CONTENTMODEL 0x00000595 +#define DISPID_SOM_CONTENTTYPE 0x00000596 +#define DISPID_SOM_DEFAULTVALUE 0x00000597 +#define DISPID_SOM_DERIVEDBY 0x00000598 +#define DISPID_SOM_DISALLOWED 0x00000599 +#define DISPID_SOM_ELEMENTS 0x0000059a +#define DISPID_SOM_ENUMERATION 0x0000059b +#define DISPID_SOM_FIELDS 0x0000059c +#define DISPID_SOM_FINAL 0x0000059d +#define DISPID_SOM_FIXEDVALUE 0x0000059e +#define DISPID_SOM_FRACTIONDIGITS 0x0000059f +#define DISPID_SOM_ID 0x000005a0 +#define DISPID_SOM_IDCONSTRAINTS 0x000005a1 +#define DISPID_SOM_ISABSTRACT 0x000005a2 +#define DISPID_SOM_ISNILLABLE 0x000005a3 +#define DISPID_SOM_ISREFERENCE 0x000005a4 +#define DISPID_SOM_ISVALID 0x000005a5 +#define DISPID_SOM_ITEMTYPE 0x000005a6 +#define DISPID_SOM_LENGTH 0x000005a7 +#define DISPID_SOM_MAXEXCLUSIVE 0x000005a8 +#define DISPID_SOM_MAXINCLUSIVE 0x000005a9 +#define DISPID_SOM_MAXLENGTH 0x000005aa +#define DISPID_SOM_MAXOCCURS 0x000005ab +#define DISPID_SOM_MINEXCLUSIVE 0x000005ac +#define DISPID_SOM_MININCLUSIVE 0x000005ad +#define DISPID_SOM_MINLENGTH 0x000005ae +#define DISPID_SOM_MINOCCURS 0x000005af +#define DISPID_SOM_MODELGROUPS 0x000005b0 +#define DISPID_SOM_NAME 0x000005b1 +#define DISPID_SOM_NAMESPACES 0x000005b2 +#define DISPID_SOM_NAMESPACEURI 0x000005b3 +#define DISPID_SOM_NOTATIONS 0x000005b4 +#define DISPID_SOM_PARTICLES 0x000005b5 +#define DISPID_SOM_PATTERNS 0x000005b6 +#define DISPID_SOM_PROCESSCONTENTS 0x000005b7 +#define DISPID_SOM_PROHIBITED 0x000005b8 +#define DISPID_SOM_PUBLICIDENTIFIER 0x000005b9 +#define DISPID_SOM_REFERENCEDKEY 0x000005ba +#define DISPID_SOM_SCHEMA 0x000005bb +#define DISPID_SOM_SCHEMALOCATIONS 0x000005bc +#define DISPID_SOM_SCOPE 0x000005bd +#define DISPID_SOM_SELECTOR 0x000005be +#define DISPID_SOM_SUBSTITUTIONGROUP 0x000005bf +#define DISPID_SOM_EXCLUSIONS 0x000005c0 +#define DISPID_SOM_SYSTEMIDENTIFIER 0x000005c1 +#define DISPID_SOM_TARGETNAMESPACE 0x000005c2 +#define DISPID_SOM_TOTALDIGITS 0x000005c3 +#define DISPID_SOM_TYPE 0x000005c4 +#define DISPID_SOM_TYPES 0x000005c5 +#define DISPID_SOM_UNHANDLEDATTRS 0x000005c6 +#define DISPID_SOM_USE 0x000005c7 +#define DISPID_SOM_VARIETY 0x000005c8 +#define DISPID_SOM_VERSION 0x000005c9 +#define DISPID_SOM_WHITESPACE 0x000005ca +#define DISPID_SOM_WRITEANNOTATION 0x000005cb + #endif /* __MSXML2DID_H__ */ diff --git a/include/psdk/prsht.h b/include/psdk/prsht.h index 91f3e76de14..dc1b1afedac 100644 --- a/include/psdk/prsht.h +++ b/include/psdk/prsht.h @@ -82,7 +82,11 @@ extern "C" { #if (_WIN32_IE >= 0x0500) #define PSM_GETRESULT 1159 #define PropSheet_GetResult(hDlg) SNDMSG(hDlg, PSM_GETRESULT, 0, 0) + #define PSM_HWNDTOINDEX 1153 +#define PropSheet_HwndToIndex(hDlg, hwnd) \ + (int)SNDMSG(hDlg, PSM_HWNDTOINDEX, (WPARAM)(hwnd), 0) + #define PSM_IDTOINDEX 1157 #define PSM_INDEXTOHWND 1154 #define PSM_INDEXTOID 1158 diff --git a/include/psdk/shellapi.h b/include/psdk/shellapi.h index 26fe6450873..ff7b94ea3f9 100644 --- a/include/psdk/shellapi.h +++ b/include/psdk/shellapi.h @@ -128,6 +128,19 @@ extern "C" { #define SHGFI_PIDL 8 #define SHGFI_USEFILEATTRIBUTES 16 +#if (NTDDI_VERSION >= NTDDI_WINXP) +#define SHIL_LARGE 0x0 +#define SHIL_SMALL 0x1 +#define SHIL_EXTRALARGE 0x2 +#define SHIL_SYSSMALL 0x3 +#if (NTDDI_VERSION >= NTDDI_VISTA) +#define SHIL_JUMBO 0x4 +#define SHIL_LAST SHIL_JUMBO +#else +#define SHIL_LAST SHIL_SYSSMALL +#endif +#endif + typedef struct _SHCREATEPROCESSINFOW { DWORD cbSize; diff --git a/include/psdk/urlmon.idl b/include/psdk/urlmon.idl index 2ab3b2b021d..c1d3bec3b57 100644 --- a/include/psdk/urlmon.idl +++ b/include/psdk/urlmon.idl @@ -1231,6 +1231,7 @@ interface IInternetZoneManager : IUnknown typedef enum tagURLZONE { + URLZONE_INVALID = -1, URLZONE_PREDEFINED_MIN = 0, URLZONE_LOCAL_MACHINE = 0, URLZONE_INTRANET = 1, @@ -1563,6 +1564,15 @@ interface IUri : IUnknown Uri_PROPERTY_DWORD_LAST = Uri_PROPERTY_ZONE } Uri_PROPERTY; + typedef enum + { + Uri_HOST_UNKNOWN = 0, + Uri_HOST_DNS = 1, + Uri_HOST_IPV4 = 2, + Uri_HOST_IPV6 = 3, + Uri_HOST_IDN = 4 + } Uri_HOST_TYPE; + HRESULT GetPropertyBSTR( [in] Uri_PROPERTY uriProp, [out] BSTR *pbstrProperty, diff --git a/include/psdk/wincrypt.h b/include/psdk/wincrypt.h index 3f7f4ed6e5b..540169b266d 100644 --- a/include/psdk/wincrypt.h +++ b/include/psdk/wincrypt.h @@ -3389,6 +3389,8 @@ typedef struct _CERT_CHAIN_ENGINE_CONFIG DWORD dwUrlRetrievalTimeout; DWORD MaximumCachedCertificates; DWORD CycleDetectionModulus; + HCERTSTORE hExclusiveRoot; + HCERTSTORE hExclusiveRootTrustedPeople; } CERT_CHAIN_ENGINE_CONFIG, *PCERT_CHAIN_ENGINE_CONFIG; /* message-related definitions */ diff --git a/include/psdk/wininet.h b/include/psdk/wininet.h index 1cb0508ead3..a0ec4082d12 100644 --- a/include/psdk/wininet.h +++ b/include/psdk/wininet.h @@ -122,6 +122,9 @@ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP) ) #define INTERNET_ERROR_MASK_INSERT_CDROM 0x1 +#define INTERNET_ERROR_MASK_COMBINED_SEC_CERT 0x2 +#define INTERNET_ERROR_MASK_NEED_MSN_SSPI_PKG 0x4 +#define INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY 0x8 #define INTERNET_OPTIONS_MASK (~INTERNET_FLAGS_MASK) #define WININET_API_FLAG_ASYNC 0x00000001 diff --git a/include/psdk/winnt.h b/include/psdk/winnt.h index d0e203fd206..10c4a14e39f 100644 --- a/include/psdk/winnt.h +++ b/include/psdk/winnt.h @@ -2339,8 +2339,8 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PM128A Xmm13; PM128A Xmm14; PM128A Xmm15; - }; - }; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; union { PULONG64 IntegerContext[16]; @@ -2361,8 +2361,8 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PULONG64 R13; PULONG64 R14; PULONG64 R15; - }; - }; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME2; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; #define RUNTIME_FUNCTION_INDIRECT 0x1 diff --git a/include/reactos/libs/pseh/pseh2.h b/include/reactos/libs/pseh/pseh2.h index ce1326e9ae0..6c473a4c43d 100644 --- a/include/reactos/libs/pseh/pseh2.h +++ b/include/reactos/libs/pseh/pseh2.h @@ -26,7 +26,7 @@ #ifndef KJK_PSEH2_H_ #define KJK_PSEH2_H_ -#if !defined (__arm__) +#if !defined (__arm__) && !defined(__clang__) #if defined(__GNUC__) struct _EXCEPTION_RECORD; @@ -395,7 +395,7 @@ __SEH_END_SCOPE_CHAIN; #define _SEH2_END } #define _SEH2_GetExceptionInformation() -#define _SEH2_GetExceptionCode() STATUS_SUCCESS +#define _SEH2_GetExceptionCode() 0 #define _SEH2_AbnormalTermination() #define _SEH2_YIELD(STMT_) STMT_ diff --git a/include/reactos/libs/sound/mmebuddy.h b/include/reactos/libs/sound/mmebuddy.h index 4e1583230c1..cae6f3f1489 100644 --- a/include/reactos/libs/sound/mmebuddy.h +++ b/include/reactos/libs/sound/mmebuddy.h @@ -400,8 +400,8 @@ ReleaseEntrypointMutex( VOID NotifyMmeClient( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, - IN DWORD Message, - IN DWORD Parameter); + IN UINT Message, + IN DWORD_PTR Parameter); MMRESULT MmeGetSoundDeviceCapabilities( @@ -413,20 +413,20 @@ MmeGetSoundDeviceCapabilities( MMRESULT MmeOpenWaveDevice( IN MMDEVICE_TYPE DeviceType, - IN DWORD DeviceId, + IN UINT DeviceId, IN LPWAVEOPENDESC OpenParameters, IN DWORD Flags, - OUT DWORD* PrivateHandle); + OUT DWORD_PTR* PrivateHandle); MMRESULT MmeCloseDevice( - IN DWORD PrivateHandle); + IN DWORD_PTR PrivateHandle); MMRESULT MmeGetPosition( IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN MMTIME* Time, IN DWORD Size); @@ -441,7 +441,7 @@ MmeGetDeviceInterfaceString( MMRESULT MmeSetState( - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN BOOL bStart); @@ -456,7 +456,7 @@ MmeSetState( MMRESULT MmeResetWavePlayback( - IN DWORD PrivateHandle); + IN DWORD_PTR PrivateHandle); /* diff --git a/include/reactos/subsys/csrss/csrss.h b/include/reactos/subsys/csrss/csrss.h index 0119bad99a3..1f8628ef712 100644 --- a/include/reactos/subsys/csrss/csrss.h +++ b/include/reactos/subsys/csrss/csrss.h @@ -51,10 +51,9 @@ typedef struct typedef struct { - ULONG nMaxIds; - ULONG nProcessIdsCopied; - ULONG nProcessIdsTotal; - HANDLE ProcessId[0]; + USHORT nMaxIds; + PDWORD ProcessId; + ULONG nProcessIdsTotal; } CSRSS_GET_PROCESS_LIST, *PCSRSS_GET_PROCESS_LIST; typedef struct @@ -63,6 +62,7 @@ typedef struct BOOL Unicode; ULONG NrCharactersToWrite; ULONG NrCharactersWritten; + HANDLE UnpauseEvent; BYTE Buffer[0]; } CSRSS_WRITE_CONSOLE, *PCSRSS_WRITE_CONSOLE; @@ -70,8 +70,8 @@ typedef struct { HANDLE ConsoleHandle; BOOL Unicode; + WORD FullReadSize; WORD NrCharactersToRead; - WORD nCharsCanBeDeleted; /* number of chars already in buffer that can be backspaced */ HANDLE EventHandle; ULONG NrCharactersRead; BYTE Buffer[0]; @@ -80,7 +80,8 @@ typedef struct typedef struct { PCONTROLDISPATCHER CtrlDispatcher; - BOOL ConsoleNeeded; + BOOLEAN ConsoleNeeded; + BOOLEAN Visible; HANDLE Console; HANDLE InputHandle; HANDLE OutputHandle; @@ -206,13 +207,13 @@ typedef struct typedef struct { DWORD Length; - WCHAR Title[0]; + PWCHAR Title; } CSRSS_SET_TITLE, *PCSRSS_SET_TITLE; typedef struct { DWORD Length; - WCHAR Title[0]; + PWCHAR Title; } CSRSS_GET_TITLE, *PCSRSS_GET_TITLE; typedef struct @@ -320,15 +321,10 @@ typedef struct { DWORD Access; BOOL Inheritable; - HANDLE InputHandle; -} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE; - -typedef struct -{ - DWORD Access; - BOOL Inheritable; - HANDLE OutputHandle; -} CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; + HANDLE Handle; + DWORD ShareMode; +} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE, + CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; typedef struct { @@ -478,6 +474,42 @@ typedef struct COORD Size; } CSRSS_SET_SCREEN_BUFFER_SIZE, *PCSRSS_SET_SCREEN_BUFFER_SIZE; +typedef struct +{ + CONSOLE_SELECTION_INFO Info; +} CSRSS_GET_CONSOLE_SELECTION_INFO, *PCSRSS_GET_CONSOLE_SELECTION_INFO; + +typedef struct +{ + UNICODE_STRING ExeName; + DWORD Length; +} CSRSS_GET_COMMAND_HISTORY_LENGTH, *PCSRSS_GET_COMMAND_HISTORY_LENGTH; + +typedef struct +{ + UNICODE_STRING ExeName; + PWCHAR History; + DWORD Length; +} CSRSS_GET_COMMAND_HISTORY, *PCSRSS_GET_COMMAND_HISTORY; + +typedef struct +{ + UNICODE_STRING ExeName; +} CSRSS_EXPUNGE_COMMAND_HISTORY, *PCSRSS_EXPUNGE_COMMAND_HISTORY; + +typedef struct +{ + UNICODE_STRING ExeName; + DWORD NumCommands; +} CSRSS_SET_HISTORY_NUMBER_COMMANDS, *PCSRSS_SET_HISTORY_NUMBER_COMMANDS; + +typedef struct +{ + DWORD HistoryBufferSize; + DWORD NumberOfHistoryBuffers; + DWORD dwFlags; +} CSRSS_GET_HISTORY_INFO, *PCSRSS_GET_HISTORY_INFO, + CSRSS_SET_HISTORY_INFO, *PCSRSS_SET_HISTORY_INFO; #define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) + sizeof(Type)) #define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)) @@ -486,11 +518,6 @@ typedef struct #define CSRSS_MAX_READ_CONSOLE (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)) #define CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)) #define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)) -#define CSRSS_MAX_GET_PROCESS_LIST (LPC_MAX_DATA_LENGTH - CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)) - -/* WCHARs, not bytes! */ -#define CSRSS_MAX_TITLE_LENGTH 80 -#define CSRSS_MAX_ALIAS_TARGET_LENGTH 80 #define CREATE_PROCESS (0x0) #define TERMINATE_PROCESS (0x1) @@ -557,6 +584,13 @@ typedef struct #define GENERATE_CTRL_EVENT (0x3E) #define CREATE_THREAD (0x3F) #define SET_SCREEN_BUFFER_SIZE (0x40) +#define GET_CONSOLE_SELECTION_INFO (0x41) +#define GET_COMMAND_HISTORY_LENGTH (0x42) +#define GET_COMMAND_HISTORY (0x43) +#define EXPUNGE_COMMAND_HISTORY (0x44) +#define SET_HISTORY_NUMBER_COMMANDS (0x45) +#define GET_HISTORY_INFO (0x46) +#define SET_HISTORY_INFO (0x47) /* Keep in sync with definition below. */ #define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS)) @@ -631,6 +665,13 @@ typedef struct _CSR_API_MESSAGE CSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength; CSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent; CSRSS_SET_SCREEN_BUFFER_SIZE SetScreenBufferSize; + CSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo; + CSRSS_GET_COMMAND_HISTORY_LENGTH GetCommandHistoryLength; + CSRSS_GET_COMMAND_HISTORY GetCommandHistory; + CSRSS_EXPUNGE_COMMAND_HISTORY ExpungeCommandHistory; + CSRSS_SET_HISTORY_NUMBER_COMMANDS SetHistoryNumberCommands; + CSRSS_GET_HISTORY_INFO GetHistoryInfo; + CSRSS_SET_HISTORY_INFO SetHistoryInfo; } Data; } CSR_API_MESSAGE, *PCSR_API_MESSAGE; diff --git a/include/reactos/win32k/callback.h b/include/reactos/win32k/callback.h index 7dd97948adc..fc7c0bb95e2 100644 --- a/include/reactos/win32k/callback.h +++ b/include/reactos/win32k/callback.h @@ -33,6 +33,13 @@ typedef struct _SENDASYNCPROC_CALLBACK_ARGUMENTS LRESULT Result; } SENDASYNCPROC_CALLBACK_ARGUMENTS, *PSENDASYNCPROC_CALLBACK_ARGUMENTS; +typedef struct _CALL_BACK_INFO +{ + SENDASYNCPROC CallBack; + ULONG_PTR Context; +} CALL_BACK_INFO, * PCALL_BACK_INFO; + + typedef struct _HOOKPROC_CALLBACK_ARGUMENTS { INT HookId; diff --git a/include/reactos/win32k/ntuser.h b/include/reactos/win32k/ntuser.h index 0d6d7811db7..007fa887200 100644 --- a/include/reactos/win32k/ntuser.h +++ b/include/reactos/win32k/ntuser.h @@ -3135,7 +3135,6 @@ typedef struct tagKMDDELPARAM #define NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO 0xffff0005 #define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006 -#define NOPARAM_ROUTINE_CSRSS_INITIALIZED 0xffff0007 #define ONEPARAM_ROUTINE_CSRSS_GUICHECK 0xffff0008 #define ONEPARAM_ROUTINE_SWITCHCARETSHOWING 0xfffe0008 #define ONEPARAM_ROUTINE_ISWINDOWINDESTROY 0xfffe000c diff --git a/include/reactos/wine/config.h b/include/reactos/wine/config.h index 406b5fb895d..404783b1d26 100644 --- a/include/reactos/wine/config.h +++ b/include/reactos/wine/config.h @@ -442,6 +442,12 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_OPENSSL_SSL_H */ +/* Define to 1 if you have the `z' library (-lz). */ +#define HAVE_ZLIB 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ZLIB_H 1 + /* Define to 1 if you have the `pclose' function. */ #define HAVE_PCLOSE 1 diff --git a/include/reactos/wine/test.h b/include/reactos/wine/test.h index d0d8208926c..bbd0c6b2d74 100644 --- a/include/reactos/wine/test.h +++ b/include/reactos/wine/test.h @@ -80,21 +80,21 @@ extern void winetest_vskip( const char *msg, va_list ap ); #ifdef __GNUC__ -extern int winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) )); +extern void winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) )); extern void winetest_skip( const char *msg, ... ) __attribute__((format (printf,1,2))); extern void winetest_win_skip( const char *msg, ... ) __attribute__((format (printf,1,2))); extern void winetest_trace( const char *msg, ... ) __attribute__((format (printf,1,2))); #else /* __GNUC__ */ -extern int winetest_ok( int condition, const char *msg, ... ); +extern void winetest_ok( int condition, const char *msg, ... ); extern void winetest_skip( const char *msg, ... ); extern void winetest_win_skip( const char *msg, ... ); extern void winetest_trace( const char *msg, ... ); #endif /* __GNUC__ */ -#define ok_(file, line) (winetest_set_location(file, line), 0) ? 0 : winetest_ok +#define ok_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_ok #define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip #define win_skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_win_skip #define trace_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace @@ -322,15 +322,13 @@ int winetest_vok( int condition, const char *msg, va_list args ) } } -int winetest_ok( int condition, const char *msg, ... ) +void winetest_ok( int condition, const char *msg, ... ) { va_list valist; - int rc; - + va_start(valist, msg); - rc=winetest_vok(condition, msg, valist); + winetest_vok(condition, msg, valist); va_end(valist); - return rc; } void winetest_trace( const char *msg, ... ) diff --git a/include/reactos/wine/wined3d.idl b/include/reactos/wine/wined3d.idl index 6364f9cfe89..1da7d44b738 100644 --- a/include/reactos/wine/wined3d.idl +++ b/include/reactos/wine/wined3d.idl @@ -275,9 +275,7 @@ typedef enum _WINED3DFORMAT typedef enum _WINED3DRENDERSTATETYPE { - WINED3DRS_TEXTUREHANDLE = 1, /* d3d7 */ WINED3DRS_ANTIALIAS = 2, /* d3d7 */ - WINED3DRS_TEXTUREADDRESS = 3, /* d3d7 */ WINED3DRS_TEXTUREPERSPECTIVE = 4, /* d3d7 */ WINED3DRS_WRAPU = 5, /* d3d7 */ WINED3DRS_WRAPV = 6, /* d3d7 */ @@ -291,11 +289,8 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_ZWRITEENABLE = 14, WINED3DRS_ALPHATESTENABLE = 15, WINED3DRS_LASTPIXEL = 16, - WINED3DRS_TEXTUREMAG = 17, /* d3d7 */ - WINED3DRS_TEXTUREMIN = 18, /* d3d7 */ WINED3DRS_SRCBLEND = 19, WINED3DRS_DESTBLEND = 20, - WINED3DRS_TEXTUREMAPBLEND = 21, /* d3d7 */ WINED3DRS_CULLMODE = 22, WINED3DRS_ZFUNC = 23, WINED3DRS_ALPHAREF = 24, @@ -316,9 +311,6 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_STIPPLEENABLE = 39, /* d3d7 */ WINED3DRS_EDGEANTIALIAS = 40, /* d3d7, d3d8 */ WINED3DRS_COLORKEYENABLE = 41, /* d3d7 */ - WINED3DRS_BORDERCOLOR = 43, /* d3d7 */ - WINED3DRS_TEXTUREADDRESSU = 44, /* d3d7 */ - WINED3DRS_TEXTUREADDRESSV = 45, /* d3d7 */ WINED3DRS_MIPMAPLODBIAS = 46, /* d3d7 */ WINED3DRS_ZBIAS = 47, /* d3d7, d3d8 */ WINED3DRS_RANGEFOGENABLE = 48, @@ -334,38 +326,6 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_STENCILMASK = 58, WINED3DRS_STENCILWRITEMASK = 59, WINED3DRS_TEXTUREFACTOR = 60, - WINED3DRS_STIPPLEPATTERN00 = 64, - WINED3DRS_STIPPLEPATTERN01 = 65, - WINED3DRS_STIPPLEPATTERN02 = 66, - WINED3DRS_STIPPLEPATTERN03 = 67, - WINED3DRS_STIPPLEPATTERN04 = 68, - WINED3DRS_STIPPLEPATTERN05 = 69, - WINED3DRS_STIPPLEPATTERN06 = 70, - WINED3DRS_STIPPLEPATTERN07 = 71, - WINED3DRS_STIPPLEPATTERN08 = 72, - WINED3DRS_STIPPLEPATTERN09 = 73, - WINED3DRS_STIPPLEPATTERN10 = 74, - WINED3DRS_STIPPLEPATTERN11 = 75, - WINED3DRS_STIPPLEPATTERN12 = 76, - WINED3DRS_STIPPLEPATTERN13 = 77, - WINED3DRS_STIPPLEPATTERN14 = 78, - WINED3DRS_STIPPLEPATTERN15 = 79, - WINED3DRS_STIPPLEPATTERN16 = 80, - WINED3DRS_STIPPLEPATTERN17 = 81, - WINED3DRS_STIPPLEPATTERN18 = 82, - WINED3DRS_STIPPLEPATTERN19 = 83, - WINED3DRS_STIPPLEPATTERN20 = 84, - WINED3DRS_STIPPLEPATTERN21 = 85, - WINED3DRS_STIPPLEPATTERN22 = 86, - WINED3DRS_STIPPLEPATTERN23 = 87, - WINED3DRS_STIPPLEPATTERN24 = 88, - WINED3DRS_STIPPLEPATTERN25 = 89, - WINED3DRS_STIPPLEPATTERN26 = 90, - WINED3DRS_STIPPLEPATTERN27 = 91, - WINED3DRS_STIPPLEPATTERN28 = 92, - WINED3DRS_STIPPLEPATTERN29 = 93, - WINED3DRS_STIPPLEPATTERN30 = 94, - WINED3DRS_STIPPLEPATTERN31 = 95, WINED3DRS_WRAP0 = 128, WINED3DRS_WRAP1 = 129, WINED3DRS_WRAP2 = 130, @@ -407,8 +367,6 @@ typedef enum _WINED3DRENDERSTATETYPE WINED3DRS_COLORWRITEENABLE = 168, WINED3DRS_TWEENFACTOR = 170, WINED3DRS_BLENDOP = 171, - WINED3DRS_POSITIONORDER = 172, - WINED3DRS_NORMALORDER = 173, WINED3DRS_POSITIONDEGREE = 172, WINED3DRS_NORMALDEGREE = 173, WINED3DRS_SCISSORTESTENABLE = 174, @@ -3452,6 +3410,15 @@ interface IWineD3DDevice : IWineD3DBase [in] D3DCB_ENUMRESOURCES callback, [in] void *data ); + HRESULT GetSurfaceFromDC( + [in] HDC dc, + [out] IWineD3DSurface **surface + ); + HRESULT AcquireFocusWindow( + [in] HWND window + ); + void ReleaseFocusWindow( + ); } IWineD3D *WineDirect3DCreate(UINT dxVersion, IUnknown *parent); diff --git a/lib/3rdparty/3rdparty.rbuild b/lib/3rdparty/3rdparty.rbuild index 7f0c2006e45..92ecd8abc7c 100644 --- a/lib/3rdparty/3rdparty.rbuild +++ b/lib/3rdparty/3rdparty.rbuild @@ -1,6 +1,9 @@ + + -Wno-unused-value + diff --git a/lib/3rdparty/freetype/ChangeLog b/lib/3rdparty/freetype/ChangeLog index cd5a4df4cc1..83a7d53c6d4 100644 --- a/lib/3rdparty/freetype/ChangeLog +++ b/lib/3rdparty/freetype/ChangeLog @@ -1,3 +1,5498 @@ +2010-02-13 Werner Lemberg + + * Version 2.3.12 released. + ========================== + + + Tag sources with `VER-2-3-12'. + + * docs/CHANGES: Updated. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.12. + + * README, Jamfile (RefDoc), + builds/win32/vc2005/freetype.vcproj, builds/win32/vc2005/index.html, + builds/win32/vc2008/freetype.vcproj, builds/win32/vc2008/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualc/index.html, builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj, + builds/win32/visualce/index.html, + builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2005-ce/index.html, + builds/wince/vc2008-ce/freetype.vcproj, + builds/wince/vc2008-ce/index.html: s/2.3.11/2.3.12/, s/2311/2312/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 12. + + * builds/unix/configure.raw (version_info): Set to 10:0:4. + +2010-02-12 suzuki toshiya + + Improve autotool version checking to work with beta releases. + + * autogen.sh (check_tool_version): Improve the extraction of version + number from "tool --version" output. Some beta releases of + autotools have extra strings before version number. + +2010-02-12 suzuki toshiya + + Fix overallocating bug in FT_Outline_New_Internal(). + + * src/base/ftoutln.c (FT_Outline_New_Internal): The length of + FT_Outline->points[] should be numPoints, not 2 * numPoints. + Found by Paul Messmer, see + http://lists.gnu.org/archive/html/freetype-devel/2010-02/msg00003.html + +2010-02-10 Ken Sharp + + Really fix Savannah bug #28678 (part 2). + + Since we consider `sbw' for the horizontal direction only, we still have + to synthesize vertical metrics if the user wants to use the vertical + writing direction. + + * src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c + (cid_slot_load_glyph), src/type1/t1gload.c (T1_Load_Glyph): + Synthesize vertical metrics (only) if FT_LOAD_VERTICAL_LAYOUT is + set. + +2010-02-10 Ken Sharp + + Really fix Savannah bug #28678 (part 1). + + After long discussion, we now consider the character width vector + (wx,wy) returned by the `sbw' Type 1 operator as being part of *one* + direction only. For example, if you are using the horizontal + writing direction, you get the horizontal and vertical components of + the advance width for this direction. Note that OpenType and CFF fonts + don't have such a vertical component; instead, the GPOS table can be + used to generate two-dimensional advance widths (but this isn't + handled by FreeType). + + * include/freetype/ftincrem.h (FT_Incremental_MetricsRec): Add + `advance_v' field to hold the vertical component of the advance + value. + + * src/truetype/ttgload.c (tt_get_metrics), src/cff/cffgload.c + (cff_slot_load), src/type1/t1gload.c + (T1_Parse_Glyph_And_Get_Char_String), src/cid/cidgload.c + (cid_load_glyph): Use it. + +2010-02-08 Werner Lemberg + + * devel/ftoption.h [FT_CONFIG_OPTION_PIC]: Define. + +2010-02-04 suzuki toshiya + + Prevent NULL pointer dereference passed to FT_Module_Requester. + + * src/sfnt/sfdriver.c (sfnt_get_interface): Don't use `module'. + * src/psnames/psmodule.c (psnames_get_interface): Ditto. + + * src/cff/cffdrivr.c (cff_get_interface): Check NULL `driver'. + * src/truetype/ttdriver.c (tt_get_interface): Ditto. + +2010-01-29 suzuki toshiya + + Fix memory leaks in previous patch. + + * src/sfnt/sfobjs.c (sfnt_load_face): Don't overwrite the strings + allocated for face->root.family_name and style_name. + +2010-01-29 suzuki toshiya + + New parameters for FT_Open_Face() to ignore preferred family names. + + Preferred family names should be used for legacy systems that + can hold only a few faces (<= 4) for a family name. Suggested by + Andreas Heinrich. + http://lists.gnu.org/archive/html/freetype/2010-01/msg00001.html + + * include/freetype/ftsnames.h (FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY, + FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY): Define. + + * src/sfnt/sfobjs.h (sfnt_load_face): Check the arguments and + ignore preferred family and subfamily names if requested. + +2010-01-27 Ken Sharp + + Fix Savannah bug #28678. + + * src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c + (cid_load_glyph): Handle vertical metrics correctly. + + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Handle + vertical metrics correctly. + (T1_Load_Glyph): Don't synthesize vertical metrics. + +2010-01-14 Werner Lemberg + + Make FT_Set_Transform work if no renderer is available. + + * src/base/ftobjs.c (FT_Load_Glyph): Apply `standard' transformation + if no renderer is compiled into the library. + +2010-01-14 Werner Lemberg + + Fix compilation warning. + + * src/base/ftbase.h: s/LOCAL_DEF/LOCAL/. + * src/base/ftobjc.s: Include ftbase.h conditionally. + +2010-01-11 Kwang Yul Seo + + Provide inline assembly code for RVCT compiler. + This is Savannah patch #7059. + + * include/freetype/config/ftconfig.h (FT_MULFIX_ASSEMBLER, + FT_MulFix_arm) [__CC_ARM || __ARM_CC]: Define. + +2010-01-08 Ken Sharp + + Fix Savannah bug #28521. + + Issue #28226 involved a work-around for a font which used the + `setcurrentpoint' operator in an invalid way; this operator is only + supposed to be used with the result of OtherSubrs, and the font used + it directly. The supplied patch removed the block of code which + checked this usage entirely. + + This turns out to be a Bad Thing. If `setcurrentpoint' is being + used correctly it should reset the flex flag in the decoder. If we + don't do this then the flag never gets reset and we omit any further + contours from the glyph (at least until we close the path or + similar). + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : Handle `flex_state' correctly. + +2010-01-05 Werner Lemberg + + Apply reports from clang static analyzer. + + * src/lzw/ftlzw.c (ft_lzw_file_init), src/base/ftstroke.c + (FT_Stroker_ParseOutline), src/base/ftsynth.c + (FT_GlyphSlot_Embolden): Remove dead code. + + * src/base/ftpatent.c (_tt_check_patents_in_table): Initialize + `offset_i' and `length_i'. + +2010-01-05 Ralph Giles + + Enable the incremental font interface by default. + + Ghostscript requires the incremental font interface for handling + some Postscript documents. It is moving to using FreeType as its + primary renderer; supporting this in the default build makes it + Ghostscript to be linked against the system FreeType when one is + available. + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_INCREMENTAL): + Uncomment. + +2010-01-05 Werner Lemberg + + Fix Savannah bug #28395. + + * src/truetype/ttdriver.c (Load_Glyph), src/type1/t1gload.c + (T1_Loada_Glyph): Don't check `num_glyphs' if incremental interface + is used. + +2010-01-05 Ken Sharp + + Make Type 1 `seac' operator work with incremental interface. + This fixes Savannah bug #28480. + + * src/psaux/t1decode.c (t1operator_seac): Don't check `glyph_names' + if incremental interface is used. + +2010-01-04 Ken Sharp + + Make incremental interface work with TrueType fonts. + This fixes Savannah bug #28478. + + * src/truetype/ttgload.c (load_truetype_glyph): Don't check + `glyf_offset' if incremental interface is used. + +2009-12-31 Lars Abrahamsson + + Make compilation with FT_CONFIG_OPTION_PIC work again. + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap) [FT_CONFIG_OPTION_PIC]: + Declare `library' for FT_BITMAP_GLYPH_CLASS_GET. + + * src/base/ftinit.c (ft_destroy_default_module_classes, + ft_create_default_module_classes): Use proper casts (needed for C++ + compilation). + + * src/sfnt/ttcmap.c (tt_cmap13_class_rec): Use FT_DEFINE_TT_CMAP. + +2009-12-22 Marc Kleine-Budde + + Make freetype-config aware of $SYSROOT. + This is Savannah patch #7040. + + * builds/unix/freetype-config.in: Decorate with ${SYSROOT} where + appropriate. + +2009-12-20 Werner Lemberg + + Fix compiler warning. + Reported by Sean. + + * src/base/ftdbgmem.c [!FT_DEBUG_MEMORY]: ANSI C doesn't like empty + source files; however, some compilers warn about an unused variable + declaration. This is now replaced with a typedef. + +2009-12-18 Werner Lemberg + + Fix Savannah bug #28320. + + There exist corrupt, subsetted fonts (embedded in PDF files) which + contain a private dict that ends with an unterminated floating point + number (no operator following). We now ignore this error (as + acrobat does). + + * src/cff/cffparse.c (cff_parser_run): Don't emit a syntax error for + unterminated floating point numbers. + +2009-12-16 Werner Lemberg + + Really fix compiler warnings. + Reported by Sean. + + * src/truetype/ttgxvar.c (GX_PT_POINTS_ARE_WORDS, + GX_PT_POINT_RUN_COUNT_MASK): Convert enum values to macros. + +2009-12-16 suzuki toshiya + + Improve configure.raw to copy some options from CFLAGS to LDFLAGS. + The linker of Mac OS X 10.6 is sensitive to the architecture. If + the architectures are specified explicitly for the C compiler, the + linker requires the architecture specifications too. + + * builds/unix/configure.raw: Replace `-isysroot' option parser by + more generic argument parser. + +2009-12-15 Werner Lemberg + + Fix compiler warnings. + Reported by Sean. + + * src/truetype/ttgxvar.c (ft_var_readpackeddeltas): Fix counter data + type. + +2009-12-14 Ken Sharp + + Ignore invalid `setcurrentpoint' operations in Type 1 fonts. + This fixes Savannah bug #28226. + + At least two wild PostScript files of unknown provenance contain + Type 1 fonts, apparently converted from TrueType fonts in earlier + PDF versions of the files, which use the `setcurrentpoint' operator + inappropriately. + + FreeType currently throws an error in this case, but Ghostscript and + Adobe Distiller both accept the fonts and ignore the problem. This + commit #ifdefs out the check so PostScript interpreters using + FreeType can render these files. + + The specification says `setcurrentpoint' should only be used to set + the point after a `Subr' call, but these fonts use it to set the + initial point to (0,0). Unnecessarily so, as they correctly use an + `hsbw' operation which implicitly sets the initial point. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : Comment out code. + +2009-12-14 Bram Tassyns + + Fix parsing of /CIDFontVersion. + This fixes Savannah bug #28287. + + * src/cid/cidtoken.h: `cid_version' in CID_FaceInfoRec (in + t1tables.h) is of type FT_Fixed. + +2009-12-14 Werner Lemberg + + Trace glyph index in CID module. + Suggested in Savannah patch #7023. + + * src/cid/cidgload.c (cid_load_glyph): Add tracing message. + +2009-12-03 Werner Lemberg + + Fix compiler warnings. + + * src/truetype/ttgload.c (tt_get_metrics): Put `Exit' label into the + proper preprocessor conditional. + * src/pfr/pfrobjs.c (pfr_slot_load): Pacify gcc. + +2009-11-25 John Tytgat + + Better handling of start of `eexec' section. + This fixes Savannah bug #28090. + + * src/type1/t1parse.c (T1_Get_Private_Dict): Skip all whitespace + characters before start of `eexec' section. + +2009-11-20 Werner Lemberg + + Fix Savannah bug #27742. + + * src/base/ftstroke.c (ft_stroker_outside): Avoid silent division by + zero, using a threshold for `theta'. + +2009-11-20 Werner Lemberg + + Fix Savannah bug #28036. + + * src/type1/t1afm.c (t1_get_index): Fix comparison. + +2009-11-16 Werner Lemberg + + Fix compiler warnings. + Reported by Kevin Blenkinsopp . + + * src/sfnt/ttload.c (check_table_dir): Use proper data type. + +2009-11-15 Werner Lemberg + + Really fix FreeDesktop bug #21197. + This also fixes Savannah bug #28021. + + * src/autofit/aflatin.c (af_latin_metrics_check_digits), + src/autofit/aflatin2.c (af_latin2_metrics_check_digits): Fix loop. + +2009-11-15 Werner Lemberg + + Add tracing messages for advance values. + + * src/base/ftobjs.c (FT_Load_Glyph), src/truetype/ttgload.c + (TT_Get_HMetrics, TT_Get_VMetrics): Do it. + +2009-11-08 Werner Lemberg + + Fix compiler warning. + Reported by Jeremy Manson . + + * src/truetype/ttgload.c (load_truetype_glyph): Initialize `error'. + +2009-11-04 Werner Lemberg + + Remove compiler warning. + Reported by Sean McBride . + + * src/tools/apinames.c (read_header_file): Use a cast to + `int', as specified in the printf(3) man page. + +2009-11-04 Werner Lemberg + + Fix Savannah bug #27921. + + * src/cff/cffobjs.c (cff_face_init), src/cid/cidobjs.c + (cid_face_init), src/type1/t1afm.c (T1_Read_Metrics), + src/type1/t1objs.c (T1_Face_Init): Don't use unsigned constant + values for rounding if the argument can be negative. + +2009-11-03 Bram Tassyns + + Add basic support for Type1 charstrings in CFF. + This fixes Savannah bug #27922. + + * src/cff/cffgload.c (CFF_Operator, cff_argument_counts): Handle + `seac', `sbw', and `setcurrentpoint' opcodes. + (cff_compute_bias): Add parameter to indicate the charstring type. + Update all callers. + (cff_operator_seac): Add parameter for side bearing. + (cff_decoder_parse_charstrings): Updated for more Type1 support. + +2009-11-03 Werner Lemberg + + Return correct `linearHoriAdvance' value for embedded TT bitmaps too. + Reported by Jeremy Manson . + + src/truetype/ttgload.c (load_truetype_glyph): Add parameter to + quickly load the glyph header only. + Update all callers. + (tt_loader_init): Add parameter to quickly load the `glyf' table + only. + Update all callers. + (TT_Load_Glyph): Compute linear advance values for embedded bitmap + glyphs too. + +2009-11-03 Werner Lemberg + + Improve code readability. + + * src/ttgload.c (load_truetype_glyph): Move metrics calculation + to... + (tt_get_metrics): This new function. + +2009-10-26 Bram Tassyns + + Fix Savannah bug #27811. + + * src/truetype/ttxgvar.c (ft_var_readpackeddeltas): Fix + signed/unsigned mismatch. + +2009-10-19 Ning Dong + + Fix handling of `get' and `put' CFF instructions. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings) : Appendix B of Adobe Technote #5177 limits the number of + elements for the `get' and `put' operators to 32. + * src/cff/cffgload.h (CFF_MAX_TRANS_ELEMENTS): Define. + (CFF_Decoder): Use it for `buildchar' and remove `len_buildchar'. + +2009-10-18 Werner Lemberg + + Fix handling of `dup' CFF instruction. + Problem and solution reported by Ning Dong . + + * src/cff/cffgload.c (cff_decoder_parse_charstrings) : + Increase `args' by 2, not 1. + +2009-10-10 Werner Lemberg + + * Version 2.3.11 released. + ========================== + + + Tag sources with `VER-2-3-11'. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.11. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.10/2.3.11/, s/2310/2311/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 11. + + * builds/unix/configure.raw (version_info): Set to 9:22:3. + +2009-10-10 Werner Lemberg + + * docs/CHANGES, docs/release: Updated. + +2009-10-10 suzuki toshiya + + * src/pcf/pcfread.c (pcf_get_properties): Fix a bug in the nprops + truncation. Reported by Martin von Gagern and Peter Volkov. + https://bugs.gentoo.org/288357 and https://bugs.gentoo.org/288256 + +2009-10-06 Werner Lemberg + + * Version 2.3.10 released. + ========================== + + + Tag sources with `VER-2-3-10'. + + * builds/toplevel.mk (major, minor, patch): Fix regexp to allow more + than a single digit. + (dist): We now use git. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.10. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.9/2.3.10/, s/239/2310/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 10. + + * builds/unix/configure.raw (version_info): Set to 9:21:3. + +2009-10-06 Werner Lemberg + + Fix `make multi'. + + * src/cache/ftccache.c, src/cache/ftcsbits.c (FT_COMPONENT): Define. + + * src/sfnt/sfdriver.c: Include FT_INTERNAL_DEBUG_H. + +2009-09-27 suzuki toshiya + + [cache] Fix Savannah bug #27441, clean up Redhat bugzilla #513582. + Tricky casts in FTC_{CACHE,GCACHE,MRULIST}_LOOKUP_CMP() are removed. + Now these functions should be called with FTC_Node or FTC_MruNode + variable, and the caller should cast them to appropriate pointers to + concrete data. These tricky casts can GCC-4.4 optimizer (-O2) + confused and the crashing binaries are generated. + + * src/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): Drop tricky cast. + Now the 4th argument `node' of this function should be typed as + FTC_MruNode. + + * src/cache/ftcglyph.h (FTC_GCACHE_LOOKUP_CMP): For inline + implementation, new temporal variable FTC_MruNode `_mrunode' to take + the pointer from FTC_MRULIST_LOOKUP_CMP(). For non-inline + implementation, tricky cast is dropped. + + * src/cache/ftcmanag.c (FTC_SIZE_NODE): New macro casting + to FTC_SizeNode. + (FTC_Manager_LookupSize): Replace FTC_SizeNode `node' by FTC_MruNode + `mrunode', and FTC_SIZE_NODE() is inserted. + (FTC_FACE_NODE): New macro casting to FTC_FaceNode. + (FTC_Manager_LookupFace) Replace FTC_FaceNode `node' by FTC_MruNode + `mrunode', and FTC_FACE_NODE() is inserted. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): Change the type of + `node' from FTC_INode to FTC_Node. Extra casting macro FTC_NODE() + is dropped. + (FTC_ImageCache_LookupScaler): Ditto. + (FTC_SBitCache_Lookup): Change the type of `node' from FTC_SNode to + FTC_Node. Extra casting macro FTC_NODE() is dropped. FTC_SNODE() + is inserted. + (FTC_SBitCache_LookupScaler): Ditto. + + * src/cache/ftccmap.c (FTC_CMapCache_Lookup): Change the type of + `node' from FTC_CMapNode to FTC_Node. Extra casting macro + FTC_NODE() is dropped, FTC_CMAP_NODE() is inserted. + +2009-09-25 suzuki toshiya + + [cache, psaux, type1] Fix for multi build. + In multi build, some cpp functions are left as unresolved symbols. + + * src/cache/ftcbasic.c: Include FT_INTERNAL_DEBUG_H for FT_TRACE1(). + + * src/psaux/t1decode.c: Include FT_INTERNAL_CALC_H for + FIXED_TO_INT(). + * src/type1/t1gload.c: Ditto. + * src/type1/t1objs.c: Ditto. + +2009-09-25 suzuki toshiya + + [autofit] Fix for multi build. + + * src/autofit/afmodule.h: Include FT_INTERNAL_OBJECTS_H to use + FT_DECLARE_MODULE() macro in multi build. + + * src/autofit/aflatin.c: Include to handle + FT_ADVANCES_H correctly in multi build. + +2009-09-24 suzuki toshiya + + [cache] Check the face filled by FTC_Manager_LookupFace(). + + * src/cache/ftcbasic.c (ftc_basic_family_get_count): Return + immediately if FTC_Manager_LookupFace() fills face by NULL. Such + case can occur when the code is optimized by GCC-4.2.x. + +2009-09-23 Werner Lemberg + + * docs/CHANGES: Updated. + +2009-09-12 Werner Lemberg + + [raster] Fix 5-levels grayscale output. + This was broken since version 2.3.0. + + * src/raster/ftraster.c (count_table): Use pre-2.3.0 values (which + were then computed dynamically). + (Vertical_Gray_Sweep_Step): Updated. + + (ft_black_render): Initialize `worker->gray_lines' (problem found by + valgrind). + + (FT_RASTER_OPTION_ANTI_ALIASING, DEBUG_RASTER): Dont' #undef, just + comment out. + +2009-09-12 suzuki toshiya + + Improve configure.raw for cross build. + + * builds/unix/configure.raw: Remove temporal files created by the + suffix checking for CC_BUILD. Set XX_ANSIFLAGS and XX_CFLAGS when + cross compiler is GCC. AC_PROG_CC checks whether the cross compiler + is GCC, its result is stored in GCC. + +2009-09-12 suzuki toshiya + + [BDF] Modify hash API to take size_t value instead of void *. + + The hash API in BDF driver is designed to be generic, it takes + void * typed data. But BDF driver always gives an unsigned long + integer (the index to a property). To reduce non-essential + casts from unsigned long to void* and from void* to unsigned + long, the hash API is changed to take size_t integer. + The issue of incompatible cast between unsigned long and void* + on LLP64 platform is reported by NightStrike from MinGW-Win64 + project. See + http://lists.gnu.org/archive/html/freetype/2009-09/msg00000.html + + * src/bdf/bdf.h: The type of hashnode->data is changed from + void* to size_t. + + * src/bdf/bdflib.c (hash_insert): Get size_t data, instead of + void* data. + (bdf_create_property): Get the name length of new property by + size_t variable, with a cut-off at FT_ULONG_MAX. + (_bdf_set_default_spacing): Get the name length of the face by + size_t variable, with a cut-off at 256. + (bdf_get_property): Get the property id by size_t variable to + reduce the casts between 32-bit prop ID & hashnode->data during + simple copying. + (_bdf_add_property): Ditto. + (_bdf_parse_start): Calculate the index to the property array + by size_t variable. + (bdf_get_font_property): Drop a cast to unsigned long. + +2009-09-10 suzuki toshiya + + [Win64] Improve the computation of random seed from stack address. + + On LLP64 platform, the conversion from pointer to FT_Fixed need + to drop higher 32-bit. Explict casts are required. Reported by + NightStrike from MinGW-w64 project. See + http://lists.gnu.org/archive/html/freetype/2009-09/msg00000.html + + * src/cff/cffgload.c: Convert the pointers to FT_Fixed explicitly. + + * src/psaux/t1decode.c: Ditto. + + +2009-09-03 Werner Lemberg + + [raster] Improvements for stand-alone mode. + + * src/raster/rules.mk: Don't handle ftmisc.h. It is needed for + stand-alone mode only. + + * src/raster/ftmisc.h (FT_MemoryRec , FT_Alloc_Func, FT_Free_Func, + FT_Realloc_Func): Copy declarations from ftsystem.h. + +2009-09-02 Bram Tassyns + + Improve vertical metrics calculation (Savannah bug #27364). + + The calculation of `vertBearingX' is not defined in the OTF font + spec so FreeType does a `best effort' attempt. However, this value + is defined in the PDF and PostScript specs, and that algorithm is + better than the one FreeType currently uses: + + FreeType: Use the middle of the bounding box as the X coordinate + of the vertical origin. + + Adobe PDF spec: Use the middle of the horizontal advance vector as + the X coordinate of the vertical origin. + + FreeType's algorithm goes wrong if you have a really small glyph + (like the full-width, circle-like dot at the end of the sentence, as + used in CJK scripts) with large bearings. With the FreeType + algorithm this dot gets centered on the baseline; with the PDF + algorithm it gets the correct location (in the top right). Note + that this is a serious issue, it's like printing the dot at the end + of a Roman sentence at the center of the textline instead of on the + baseline like it should. So i believe the PDF spec's algorithm + should be used in FreeType as well. + + The `vertBearingY' value for such small glyphs is also very strange + if no `vmtx' information is present, since the height of the bbox is + not representable for the height of the glyph visually (the + whitespace up to the baseline is part of the glyph). The fix also + includes some code for a better estimate of `vertBearingY'. + + * src/base/ftobjs.c (ft_synthesize_vertical_metrics): `vertBearingX' + is now calculated as described by the Adobe PDF Spec. Estimate for + `vertBearingY' now works better for small glyphs completely above or + below the baseline into account. + + * src/cff/cffgload.c (cff_slot_load): `vertBearingX' is now + calculated as described by the Adobe PDF Spec. Vertical metrics + information was always ignored when FT_CONFIG_OPTION_OLD_INTERNALS + was not defined. + + * src/truetype/ttgload.c (compute_glyph_metrics): `vertBearingX' is + now calculated as described by the Adobe PDF Spec. + +2009-09-01 John Tytgat + + Fix custom cmap for empty Type 1 font (Savannah bug #27294). + + * include/freetype/internal/t1types.h (T1_EncodingRecRec_): Update + comment to reflect revised code_last meaning. + * src/type1/t1load.c (T1_Open_Face), src/type42/t42objs.c + (T42_Open_Face): Assign max_char as highest character code + 1 and + use this for T1_EncodingRecRec_::code_last. + * src/psaux/t1cmap.c (t1_cmap_custom_init): Follow revised + T1_EncodingRecRec_::code_last meaning. + +2009-08-25 Werner Lemberg + + Fix rendering of horizontally compressed CFFs. + Bug reported by Ivan Nincic . + + * src/cff/cffgload.c (cff_slot_load): Thinko: Check `xx' element of + `font_matrix' also. + + * docs/CHANGES: Updated. + +2009-08-03 suyu0925@gmail.com + + Don't call `ft_fseek' every time when executing `ft_fread'. + + * src/base/ftstream.c (FT_Stream_Seek), src/base/ftsystem.c + (ft_ansi_stream_io): Implement it. + +2009-07-31 suzuki toshiya + + sfnt: Cast a charcode to 32-bit in cmap format 14 parser. + + * src/sfnt/ttcmap.c (tt_cmap14_char_var_index, + tt_cmap14_char_var_isdefault, tt_cmap14_char_variants, + tt_cmap14_variant_chars): Correct mismatches from + FT_CMap_CharVarIndexFunc prototype, FT_ULong arguments + are replaced by FT_UInt32 arguments. + +2009-07-31 suzuki toshiya + + sfnt: Cast a charcode to 32-bit in cmap format 12 parser. + + * src/sfnt/ttcmap.c (tt_cmap12_char_next): + Insert explicit cast from FT_UFast to FT_UInt32 + for return value. + +2009-07-31 suzuki toshiya + + psaux: Fix a few casts to FT_Int32 value. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): + Fix a few casts setting `value' from FT_Long to FT_Int32, + because `value' is typed as FT_Int32 since 2009-06-22. + +2009-07-31 suzuki toshiya + + sfnt: Fix a data type mismatching with its source. + + * src/sfnt/ttcmap.c (tt_cmap13_char_next): Fix the + type of `gindex' from FT_ULong to FT_UInt because + it is set by FT_UInt tt_cmap13_char_map_binary() or + TT_CMap13->cur_gindex. + +2009-07-31 suzuki toshiya + + sfnt: Extend a few local variables to load 32-bit values. + + * src/sfnt/ttkern.c (tt_face_load_kern): Extend `count' + and `kern' to load 32-bit values. + +2009-07-31 suzuki toshiya + + pfr: Extend `num_aux' to take 32-bit value. + + * src/pfr/pfrload.c (pfr_phy_font_load): Extend + `num_aux' to load 32-bit value. + +2009-07-31 suzuki toshiya + + pcf: Truncate FT_ULong `nprops' to fit to int PCF_Face->nprops. + + * src/pcf/pcfread.c (pcf_get_properties): Load `nprops' + as FT_ULong value from PCF file, but truncate it as + int to fit PCF_Face->nprops. The number of truncated + properties is shown in the trace message. + +2009-07-31 suzuki toshiya + + gxvalid: Extend a few local variables to reduce the casts. + + * src/gxvalid/gxvmorx.c (gxv_morx_subtables_validate): + Extend `type' and `rest' to take FT_ULong values. + +2009-07-31 suzuki toshiya + + gxvalid: Extend `settingTable' to take 32-bit offset. + + * src/gxvalid/gxvfeat.c (gxv_feat_name_validate): + Extend `settingTable' to take 32-bit offset. + +2009-07-31 suzuki toshiya + + autofit: Cast FT_Long glyph_count to compare with FT_UInt GID. + + * src/autofit/afglobal.c (af_face_globals_is_digit, + af_face_globals_compute_script_coverage): Cast FT_Long + globals->glyph_count to FT_ULong, to compare with FT_UInt + gindex. + +2009-07-31 suzuki toshiya + + smooth: Exclude 16-bit system in invalid pitch/height check. + + * src/smooth/ftsmooth.c (ft_smooth_render_generic): + pitch and height are typed as FT_UInt but checked to fit + 16-bit range, to avoid the overflows. On 16-bit system, + this checking inserts a conditional that never occurs. + +2009-07-03 suzuki toshiya + + cff: Type large constants > 0x7FFF as long for 16-bit systems. + + * src/cff/cffload.c (cff_charset_load): Type large + constants > 0x7FFF as long, because normal constants + are typed signed integer that is less than 0x8000 on + 16-bit systems. + +2009-07-31 suzuki toshiya + + base: Remove an unused variable. + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Remove an + unused variable `library'. glyph->library is used. + +2009-07-31 suzuki toshiya + + cache: Check higher bits in flags for non ILP32 systems. + + 4 public functions ought to take FT_ULong flags, but take + FT_UInt flags. To keep binary compatibility, we drop higher + bits on non ILP32 platforms, + ILP64 systems: No drop occurs. + LP64 systems: Higher bits are not used. + 16-bit systems: Drop can occur. + See + http://lists.gnu.org/archive/html/freetype-devel/2008-12/msg00065.html + These functions will be refined to take FT_ULong flags in + next bump with incompatible API change. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): + Check `flags' in `type', the 2nd argument. + (FTC_SBitCache_Lookup): Ditto. + (FTC_ImageCache_LookupScaler): Check `load_flags', + the 3rd argument. + (FTC_SBitCache_LookupScaler): Ditto. + +2009-07-31 suzuki toshiya + + sfnt: Ignore invalid GIDs in glyph name lookup. + + * include/freetype/internal/fttrace.h: + New trace module for sfdriver.c is added. + + * src/sfnt/sfdriver.c (sfnt_get_name_index): + Restrict glyph name lookup to FT_UInt GID. + Genuine TrueType can hold 16-bit glyphs. + +2009-07-31 suzuki toshiya + + pcf: Fix a comparison between FT_Long and FT_ULong. + + * src/pcf/pcfread.c (pcf_get_bitmaps): Return an error + if PCF_Face->nemetrics is negative. + +2009-07-31 suzuki toshiya + + gxvalid: Guarantee `nFeatureFlags' size up to 32-bit. + + * src/gxvalid/gxvmort.c (gxv_mort_featurearray_validate): + Extend the 3rd argument `nFeatureFlags' to FT_ULong. + * src/gxvalid/gxvmort.h: Ditto. + +2009-07-31 suzuki toshiya + + sfnt: Insert explicit cast for LP64 system. + + * src/sfnt/ttkern.c (tt_face_load_kern): Insert + cast from unsigned long to FT_UInt32. + +2009-07-31 suzuki toshiya + + gxvalid: Guarantee `just' table size upto 32-bit. + + * src/gxvalid/gxvjust.c (gxv_just_validate): + The type of `offset' is changed from FT_UInt to + FT_Offset, for 16-bit platforms. + +2009-07-31 suzuki toshiya + + gxvalid: Guarantee `trak' table size upto 32-bit. + + * src/gxvalid/gxvtrak.c (gxv_trak_validate): + The type of `offset' is changed from FT_UInt to + FT_Offset, for 16-bit platforms. + +2009-07-31 suzuki toshiya + + type1: Fix a data type mismatching with its source. + + * include/freetype/internal/t1types.h: The type of + T1_Face->buildchar is matched with T1_Decorder->top. + +2009-07-31 suzuki toshiya + + pfr: Fix a data type mismatching with its source. + + * src/pfr/pfrtypes.h: The type of PFR_KernItem->offset + is extended from FT_UInt32 to FT_Offset, because it is + calculated with the pointer difference, in + pfr_extra_item_load_kerning_pairs(). + +2009-07-31 suzuki toshiya + + pfr: Fix a data type mismatching with its source. + + * src/pfr/pfrtypes.h: The type of PFR_PhysFont->chars_offset + is extended from FT_UInt32 to FT_Offset, because it is + calculated with the pointer difference in pfr_phy_font_load(). + +2009-07-31 suzuki toshiya + + pfr: Fix a data type mismatching with its source. + + * src/pfr/pfrtypes.h: The type of PFR_PhyFont->bct_offset + is extended from FT_UInt32 to FT_Long, because it is + loaded by FT_STREAM_POS() in pfr_phy_font_load(). + +2009-07-31 suzuki toshiya + + smooth: Improve the format in debug message. + + * src/smooth/ftgrays.c (gray_dump_cells): Improve the + format specifications to dump variables. + +2009-07-31 suzuki toshiya + + sfnt: Fix a data type mismatching with its source. + + * src/sfnt/sfobjs.c (sfnt_load_face): The type of + local `flags' is matched with FT_Face->face_flags. + +2009-07-31 suzuki toshiya + + psaux: Fix a data type mismatching with its source. + + * include/freetype/internal/psaux.h: The type of + T1_DecorderRec.buildchar is matched with + T1_DecorderRec.top. + +2009-07-31 suzuki toshiya + + truetype: Extend TrueType GX packed deltas to FT_Offset. + + * src/truetype/ttgxvar.c (ft_var_readpackeddeltas): + The type of 2nd argument `delta_cnt' is changed from + FT_Int to FT_Offset, because its source can be cvt + table size calculated from stream position. + +2009-07-31 suzuki toshiya + + truetype: Extend mmvar_len to hold size_t values. + + * src/truetype/ttgxvar.h: The type of + GX_BlendRec.mmvar_len is changed from FT_Int to + FT_Offset, because TT_Get_MM_Var() calculates it + by sizeof() results. + +2009-07-31 suzuki toshiya + + truetype: Check invalid function number in IDEF instruction. + + * src/truetype/ttinterp.c (Ins_IDEF): Check + if the operand fits to 8-bit opcode limitation. + +2009-07-31 suzuki toshiya + + truetype: Check invalid function number in FDEF instruction. + + * src/truetype/ttinterp.c (Ins_FDEF): Check + if the operand fits 16-bit function number. + +2009-07-31 suzuki toshiya + + truetype: Truncate the deltas of composite glyph at 16-bit values. + + * src/truetype/ttgload.c (load_truetype_glyph): + Insert cast from FT_Long (deltas[i].{x,y}) to + FT_Int16 in the summation of deltas[] for composite + glyphs. Because deltas[i] is typed as FT_Pos, + its component x, y are typed as FT_Long, but + their sources are always FT_Int16 when they are + loaded by ft_var_readpackeddeltas(). However, + the limitation about the summed deltas is unclear. + +2009-07-31 suzuki toshiya + + truetype: Truncate the instructions upto 16-bit per a glyph. + + * src/truetype/ttgload.c (TT_Hint_Glyph): Truncate + the instructions upto 16-bit length per a glyph. + +2009-07-31 suzuki toshiya + + truetype: Cast the numerical operands to 32-bit for LP64 systems. + + * src/truetype/ttinterp.c (Ins_SPHIX, INS_MIAP, + Ins_MIRP): Insert cast from long (args[], the + operands passed to TrueType operator) to FT_Int32 + (the argument of TT_MulFix14()). + +2009-07-31 suzuki toshiya + + truetype: Cast the project vector to 32-bit for LP64 system. + + * src/truetype/ttinterp.c (Project, DualProject): + Insert casts from FT_Pos (the arguments `dx', `dy') + to FT_UInt32 (the argument to TT_DotFix14()). + +2009-07-31 suzuki toshiya + + truetype: Cast the scaling params to 32-bit for LP64 system. + + * src/truetype/ttgload.c (TT_Process_Composite_Component): + Insert casts from long (return value of FT_MulFix()) to + FT_Int32 (the argument to FT_SqrtFixed()). + +2009-07-31 suzuki toshiya + + sfnt: Cast a character code to FT_UInt32 for LP64 system. + + * src/sfnt/ttcmap.c (tt_cmap14_char_map_nondef_binary, + tt_cmap14_variants, tt_cmap14_char_variants, + tt_cmap14_def_char_count, tt_cmap14_get_def_chars, + tt_cmap14_get_nondef_chars, tt_cmap14_variant_chars) + Insert casts when FT_UInt32 variable is loaded by + TT_NEXT_{UINT24|ULONG}. Because most of them are + compared with FT_UInt32 values in public API, replacing + FT_UFast is not recommended. + +2009-07-31 suzuki toshiya + + sfnt: Cast a character code to FT_UInt32 for LP64 system. + + * src/sfnt/ttcmap.c (tt_cmap4_init, tt_cmap4_next): + Insert the casts from unsigned long constant to + FT_UInt32. + +2009-07-31 suzuki toshiya + + sfnt: Extend TT_BDF->strings_size to FT_ULong for huge BDF. + + * include/freetype/internal/tttypes.h: The type + of TT_BDF->string_size is extended from FT_UInt32 + to FT_ULong, because BDF specification does not + restrict the length of string. + * src/sfnt/ttbdf.c: The scratch variable `strings' + to load TT_BDF->string_size is matched with + TT_BDF->string_size. + +2009-07-31 suzuki toshiya + + psaux: Handle the string length by FT_Offset variables. + + * src/psaux/afmparse.c (afm_parser_next_key, + afm_tokenize, afm_parse_track_kern, + afm_parse_kern_pairs, afm_parse_kern_data, + afm_parser_skip_section, afm_parser_parse): + The length of key is handled by FT_Offset, + instead of FT_UInt. Although the length of + PostScript strings or name object is 16-bit, + AFM_STREAM_KEY_LEN() calculates the length + from the pointer difference. + + * src/psaux/afmparse.h (afm_parser_next_key): + Ditto. + +2009-07-31 suzuki toshiya + + pcf: Fix some data types mismatching with their sources. + + * src/pcf/pcfread.c (pcf_get_bitmaps): The types + of `nbitmaps', `i', `sizebitmaps' are matched with + the type of area FT_Bitmap.pitch * FT_Bitmap.rows. + +2009-07-31 suzuki toshiya + + pcf: Handle the string length by size_t variables. + + * src/pcf/pcfread.c (pcf_interpret_style): The types + of nn, len, lengths[4] are changed to size_t, because + they are loaded by (or compared with) ft_strlen(). + + * src/pcf/pcfutil.c (BitOrderInvert, TwoByteSwap, + FourByteSwap): The type of the 2nd argument `nbytes' + is changed to size_t, for similarity with ANSI C + string functions. + + * src/pcf/pcfdrivr.c (PCF_Glyph_Load): The type of + `bytes' is changed to FT_Offset, because it is passed + to FT_ALLOC(), via ft_glyphslot_alloc_bitmap(). At + least, using unsigned type is better. + +2009-07-31 suzuki toshiya + + pcf: Fix some data types mismatching with their sources. + + * src/pcf/pcfread.c (pcf_seek_to_table_type, + pcf_has_table_type): The type of 3rd argument + `ntables' is matched with PCF_Toc->count. + +2009-07-31 suzuki toshiya + + otvalid: Truncate the glyph index to 16-bit. + + * src/otvalid/otvalid.c (otv_validate): Checks + face->num_glyphs does not exceed 16-bit limit, + pass FT_UInt num_glyphs to backend functions + otv_{GPOS|GSUB|GDEF|JSTF|MATH}_validate(). + +2009-07-31 suzuki toshiya + + cache: Insert explict casts for LP64 systems. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup, + FTC_SBitCache_Lookup): The type of FTC_ImageType->width + is FT_Int, so the cast to unsigned larger type FT_ULong + is introduced for the comparisons with 0x10000L for + LP64 platform. + +2009-07-31 suzuki toshiya + + cache: Fix some data types mismatching with their sources. + + * src/cache/ftccache.h: The type of return value + by FTC_Node_WeightFunc function is changed to + FT_Offset. The type of FTC_CacheClass->cache_size + is changed to FT_Offset, too. + + * src/cache/ftccback.h (ft_inode_weight, + ftc_snode_weight): Ditto. + + * src/cache/ftccmap.c (ftc_cmap_node_weight): Ditto. + + * src/cache/ftcimage.c (ftc_inode_weight, + FTC_INode_Weight): Ditto. + + * src/cache/ftcsbits.c (ftc_snode_weight, + FTC_SNode_Weight): Ditto. + + * src/cache/ftcmru.h: The type of + FTC_MruListClass->node_size is changed to FT_Offset, + because it is passed to FT_ALLOC() to specify the + size of buffer. + +2009-07-31 suzuki toshiya + + XXX_cmap_encoding_char_next() return FT_UInt32 values. + + * include/freetype/internal/services/svpscmap.h: + The size of the charcode value returned by + the function typed PS_Unicodes_CharNextFunc is + matched with its input charcode value. + + * src/cff/cffmap.c (cff_cmap_encoding_char_next, + cff_cmap_unicode_char_next): Ditto. + + * src/pfr/pfrmap.c (pfr_cmap_encoding_char_next): + Ditto. + + * src/psaux/t1cmap.c (t1_cmap_std_char_next, + t1_cmap_custom_char_next, t1_cmap_unicode_char_next): + Ditto. + + * src/psnames/psmodule.c (ps_unicodes_char_next): + Ditto. + + * src/winfonts/winfnt.c (fnt_cmap_char_next): + Ditto. + + * src/sfnt/ttcmap.c (tt_cmap0_char_next, + tt_cmap2_char_next, tt_cmap4_char_next, + tt_cmap6_char_next, tt_cmap10_char_next, + tt_cmap12_char_next, tt_cmap13_char_next): Ditto. + (tt_cmap14_char_variants): Handle base unicode + codepoint by FT_UInt32 variable to avoid overflow + on 16-bit platforms. + (tt_cmap14_ensure): The type of `num_results' is + extend to FT_UInt32, to cover unsigned 32-bit + `numVarSelectorRecords' in cmap14 table header. + +2009-07-31 suzuki toshiya + + truetype: Extend TT_Face->num_locations for broken TTFs. + + * include/freetype/internal/tttypes.h: + TT_Face->num_locations are extended from FT_UInt + to FT_ULong, to stand with broken huge loca table. + Some people insists there are broken TTF including + the glyphs over 16-bit limitation, in PRC market. + * src/truetype/ttpload.c (tt_face_load_loca): + Remove unrequired 16-bit truncation for FT_UInt + TT_Face->num_locations. + +2009-07-31 suzuki toshiya + + smooth: Fix some data types mismatching with their sources. + + * src/smooth/ftgrays.c: The type of `TCoord' is + matched to `TPos', because they are mixed in + gray_set_cell(). The type of TCell->x is extended + to `TPos', because gray_find_cell() sets it by + TWorker.ex. The type of TCell->cover is extended + to `TCoord', because gray_render_scanline() adds + TCoord value to it. The type of TWork.cover is matched + with TCell->cover. The types of + TWork.{max_cells,num_cells} are changed to FT_PtrDist, + because they are calculated from the memory addresses. + The type of TWork.ycount is changed to TPos, because + it is calculated from TPos variables. + (gray_find_cell): The type of `x' is matched with + its initial value ras.ex. + (gray_render_scanline): The types of `mod', `lift' + and `rem' are changed to TCoord, because their values + are set with explicit casts to TCoord. When ras.area + is updated by the differential values including + `delta', they are explicitly cast to TArea, because + the type of `delta' is not TArea but TCoord. + (gray_render_line): The type of `mod' is extended + from int to TCoord, because (TCoord)dy is added to mod. + (gray_hline): The argument `acount' is extended to + TCoord, to match with the parameters in the callers. + +2009-07-31 suzuki toshiya + + cff: Fix some data types mismatching with their sources. + + * src/cff/cffobjs.c (cff_face_init): The type of + `scaling' is matched with the scaling parameter + in FT_Matrix_Multiply_Scaled() and + FT_Vector_Transform_Scaled(). + + * src/cff/cffparse.c (cff_parse_real): The type of + `power_ten', `scaling', `exponent_add', + `integer_length', `fraction_length', + `new_fraction_length' and `shift' are matched with + the type of `exponent' to avoid unexpected truncation. + (cff_parse_fixed_scaled): The type of `scaling' is + matched with the `scaling' argument to + cff_parse_real(). + (cff_parse_fixed_dynamic): Ditto. + (cff_parse_font_matrix): The type of `scaling' is + matched with the `scaling' argument to + cff_parse_dynamic(). + +2009-07-31 suzuki toshiya + + autofit: Fix some data types mismatching with their sources. + + * src/autofit/afglobal.c: Correct the type of + AF_FaceGlobalsRec.glyph_count to match with + FT_Face->num_glyphs. + (af_face_globals_compute_script_coverage): + Insert explicit cast to compare + FT_Long AF_FaceGlobalsRec.glyph_count versus + FT_UInt gindex. The type of `nn' is changed + to scan glyph index upto AF_FaceGlobalsRec.glyph_count. + (af_face_globals_get_metrics): The type of `script_max' + is changed to cover size_t value. Insert explicit cast + to compare FT_Long AF_FaceGlobalsRec.glyph_count versus + FT_UInt gindex. + + * src/autofit/afhints.c (af_axis_hints_new_segment): + Insert explicit cast to calculate `big_max' from + integer and size_t values. + (af_axis_hints_new_edge): Ditto. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): + The type of `best_y' is matched to FT_Vector.y. + (af_latin_compute_stem_width): The type of `delta' is + matched to `dist' and `org_dist'. + +2009-07-31 suzuki toshiya + + autofit: Count the size of the memory object by ptrdiff_t. + + * src/autofit/afcjk.c (af_cjk_hint_edges): The + number of edges `n_edges' should be counted by + FT_PtrDist variable instead of FT_Int. + + * src/autofit/aflatin.c (af_latin_hint_edges): + Ditto. + + * src/autofit/aftypes.h: In AF_ScriptClassRec, + the size of metric `script_metrics_size' should + be counted by FT_Offset variable instead of FT_UInt. + + * src/autofit/afhints.c + (af_glyph_hints_align_strong_points): The cursors + for the edges `min', `max', `mid' in the memory + buffer should be typed FT_PtrDist. + +2009-07-31 suzuki toshiya + + autofit: Fix for unused variable `first'. + + * src/autofit/afhints.c (af_glyph_hints_reload): Insert + FT_UNUSED() to hide the unused variable warning. + +2009-07-31 suzuki toshiya + + Improve bitmap size or pixel variables for 16-bit systems. + + * include/freetype/config/ftstdlib.h: Introduce + FT_INT_MIN, to use in signed integer overflow in + 16-bit and 64-bit platforms. + + * include/freetype/internal/fttrace.h: Add a tracer + to ftsynth.c. + + * src/base/ftbitmap.c (FT_Bitmap_Embolden): Check + invalid strength causing integer overflow on 16-bit + platform. + + * src/base/ftcalc.c (ft_corner_orientation): Change + the internal calculation from FT_Int to FT_Long, to + avoid an overflow on 16-bit platforms. The caller of + this function should use only the sign of result, + so the cast to FT_Int is acceptable. + + * src/base/ftsynth.c: Introduce a tracer for synth module. + (FT_GlyphSlot_Embolden): Check invalid strength causing + integer overflow on 16-bit platform. + + * src/bdf/bdfdrivr.c (BDF_Face_Init): The glyph index + in FT2 API is typed as FT_UInt, although BDF driver + can handle unsigned long glyph index internally. To + avoid integer overflow on 16-bit platform, too large + glyph index should be excluded. + (BDF_Glyph_Load): The glyph pitch in FT2 is typed as + FT_UInt, although BDF driver can handle unsigned long + glyph pitch internally. To avoid integer overflow on + 16-bit platform, too large glyph pitch should not be + returned. + + * src/pfr/pfrsbit.c (pfr_slot_load_bitmap): The glyph + pitch in FT2 is typed as FT_UInt, although PFR font + format can include huge bitmap glyph with 24-bit pitch + (however, a glyph spends 16.7 pixel, it's not realistic). + To avoid integer overflow on 16-bit platform, huge + bitmap glyph should be excluded. + + * src/smooth/ftgrays.c (gray_hline): As FT_Span.x is + truncated to fit its type (16-bit short), FT_Span.y + should be truncated to fit its type (FT_Int). + + * src/cff/cffdrivr.c (cff_get_ros): CFF specification + defines the supplement in ROS as a real number. + Truncate it to fit public FT2 API. + + * src/cff/cffparse.c (cff_parse_cid_ros): Warn the + supplement if it is truncated or rounded in cff_get_ros(). + + * src/cff/cfftypes.h: Change the type of internal variable + `supplement' from FT_Long to FT_ULong to fit the signedness + to the type in public API. + +2009-07-31 suzuki toshiya + + psaux: Prevent invalid arguments to afm_parser_read_vals(). + + * src/psaux/afmparse.c (afm_parser_read_vals): Change + the type of `n' to prevent negative number how many + arguments should be parsed. + + * src/psaux/afmparse.h (afm_parser_read_vals): Ditto. + +2009-07-31 suzuki toshiya + + base: Prevent some overflows on LP64 systems. + + * src/base/ftadvance.c (FT_Get_Advances): Cast the + unsigned long constant FT_LOAD_ADVANCE_ONLY to FT_UInt32 + for LP64 platforms. + + * src/base/ftcalc.c (FT_Sqrt32): All internal variables + are changed to FT_UInt32 from FT_ULong. + (FT_MulDiv): Insert casts to FT_Int32 for LP64 platforms. + This function is designed for 32-bit integer, although + their arguments and return value are FT_Long. + + * src/base/ftobjs.c (FT_Get_Char_Index): Check `charcode' + is within unsigned 32-bit integer for LP64 platforms. + (FT_Face_GetCharVariantIndex): Check `charcode' and + `variantSelector' are within 32-bit integer for LP64 + platforms. + (FT_Face_GetCharsOfVariant): Check `variantSelector' is + within unsigned 32-bit integer for LP64 platforms. + + * src/base/fttrigon.c (ft_trig_downscale): The FT_Fixed + variable `val' and unsigned long constant FT_TRIG_SCALE + are cast to FT_UInt32, when calculates FT_UInt32. + (FT_Vector_Rotate): The long constant 1L is cast to + FT_Int32 to calculate FT_Int32 `half'. + +2009-07-31 suzuki toshiya + + cff: Cast the long variables to 32-bit for LP64 systems. + + * src/cff/cffdrivr.c (cff_get_advances): Insert + explicit cast to modify a 32-bit flag by unsigned + long constant. + + * src/cff/cffobjs.c (cff_face_init): Ditto. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): + Replace the casts to FT_Long by the casts to FT_Int32 + for LP64 platforms. + +2009-07-31 suzuki toshiya + + pcf: Improve PCF_PropertyRec.value names on LP64 platforms. + + * src/pcf/pcf.h: In PCF_PropertyRec.value, the member + `integer' is replaced by `l', `cardinal' is replaced + by `ul', to fix the difference between the name and + the types on LP64 platforms. + + * src/pcf/pcfdrivr.c (pcf_get_bdf_property): Reflect + PCF_PropertyRec.value change, with appropriate casts + to FT_Int32/FT_UInt32. Their destinations + BDF_PropertyRec.{integer|cardinal} are public and + explicitly defined as FT_Int32/FT_UInt32. + + * src/pcf/pcfread.c (pcf_get_properties, pcf_load_font): + Reflect PCF_PropertyRec.value change. + +2009-07-31 suzuki toshiya + + pcf: Fix some data types mismatching with their sources. + + * src/pcf/pcfdrivr.c (pcf_cmap_char_index): The type of + `code' is matched to PCF_Encoding->enc. + (pcf_cmap_char_next): The type of `charcode' is matched + to PCF_Encoding->enc. When *acharcode is set by charcode, + an overflow is checked and cast to unsigned 32-bit + integer. + +2009-07-31 suzuki toshiya + + bdf: Improve bdf_property_t.value names for LP64 platforms. + + * src/bdf/bdf.h: In bdf_property_t.value, the member + `int32' is replaced by `l', `card32' is replaced by + `ul', to fix the difference between the name and the + types on LP64 platforms. + + * src/bdf/bdfdrivr.c (BDF_Face_Init): Reflect + bdf_property_t.value change. + (bdf_get_bdf_property): Reflect bdf_property_t.value + change, with appropriate casts to FT_Int32/FT_UInt32. + Their destinations BDF_PropertyRec.{integer|cardinal} + are public and explicitly defined as FT_Int32/FT_UInt32. + + * src/bdf/bdflib.c (_bdf_add_property): Reflect + bdf_property_t.value change. + +2009-07-31 suzuki toshiya + + bdf: Fix some data types mismatching with their sources. + + * src/bdf/bdrdrivr.c (bdf_cmap_char_index): The type + of `code' is matched with BDF_encoding_el->enc. + (bdf_cmap_char_next): The type of `charcode' is + matched with BDF_encoding_el->enc. When *acharcode + is set by charcode, an overflow is checked and + cast to unsigned 32-bit integer. + +2009-07-31 suzuki toshiya + + autofit: Improve Unicode range definitions. + + * src/autofit/aftypes.h (AF_UNIRANGE_REC): New macro + to declare a range by two unsigned 32-bit integer, + to avoid 64-bit range definition on LP64 platforms. + + * src/autofit/aflatin.c (af_latin_uniranges): Ditto. + + * src/autofit/aflatin2.c (af_latin2_uniranges): Ditto. + + * src/autofit/afindic.c (af_indic_uniranges): Ditto. + + * src/autofit/afcjk.c (af_cjk_uniranges): Declare + the ranges by AF_UNIRANGE_REC. + +2009-07-31 suzuki toshiya + + smooth: Fix a data type mismatching with its source. + + * src/smooth/ftgrays.c (gray_sweep): The type of + `area' is matched with the 3rd argument `area' + of gray_hline(). + +2009-07-31 suzuki toshiya + + smooth: Fix a data type mismatching with its source. + + * src/smooth/ftgrays.c (gray_render_line): The type + of `area' is matched with TWorker.area. + +2009-07-31 suzuki toshiya + + cache: Disable the legacy compatibility if 16-bit system. + + * src/cache/ftcbasic.c (FTC_ImageCache_Lookup): Exclude + the legacy behaviour from 16-bit platform, because the + current hack cannot detect the caller uses this function + via legacy convension. + (FTC_SBitCache_Lookup): Ditto. + +2009-07-31 suzuki toshiya + + cache: Check 32-bit glyph index on 16-bit systems. + + * src/cache/ftcbasic.c (ftc_basic_family_get_count): + Check overflow caused by the face including large + number of glyphs > 64k. + +2009-07-31 suzuki toshiya + + cache: Fix some data types mismatching with their sources. + + * src/cache/ftccache.c (ftc_cache_resize): The types of + `p', `mask', `count' are matched with FTC_Cache->{p,mask}. + (FTC_Cache_Clear): The type of `old_index' is matched to + FTC_Cache->{p,mask}. + + * src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP): The type + of `_idx' is matched with FTC_Cache->{p,mask}. + +2009-07-31 suzuki toshiya + + cache: Fix some data types mismatching with their sources. + + * src/cache/ftcsbits.c (ftc_snode_load): The types + of `xadvance' and `yadvance' are matched with + FT_GlyphSlot->advance.{x|y}. + +2009-07-31 suzuki toshiya + + cache: Cast NULL to a required function type explicitly. + + * src/cache/ftcmanag.c (FTC_Manager_RemoveFaceID): + Insert explicit cast from NULL to function type. + +2009-07-31 suzuki toshiya + + fttypes.h: Cast FT_MAKE_TAG output to FT_Tag exlicitly. + + * include/freetype/fttypes.h (FT_MAKE_TAG): + Cast the result to FT_Tag. + +2009-07-31 suzuki toshiya + + psnames: Handle Unicode codepoints by FT_UInt32 variables. + + * src/psnames/psmodule.c (BASE_GLYPH): Cast the result + to unsigned 32-bit integer for LP64 platform. + (ps_unicode_value): Return the value by unsigned 32-bit + integer instead of unsigned long. + +2009-07-31 suzuki toshiya + + psaux: Use size_t variable to pass the buffer size. + + * src/psaux/psaux.h (to_bytes): The type of `max_bytes' + (the argument to pass the buffer size) is changed to + size_t, to match with ANSI C string functions. + + * src/psaux/psconv.h (PS_Conv_StringDecode, + PS_Conv_ASCIIHexDecode, PS_Conv_EexecDecode): Ditto. + + * src/psaux/psconv.c (PS_Conv_StringDecode, + PS_Conv_ASCIIHexDecode, PS_Conv_EexecDecode): Ditto. + + * src/psaux/psobjs.h (ps_parser_to_bytes): Ditto. + + * src/psaux/psobjs.c (ps_parser_to_bytes): Ditto. + +2009-07-31 suzuki toshiya + + type1: Use size_t variable to pass the string length. + + * psaux.h: The type of `len' (the argument to pass + the buffer size to the function in AFM_ParserRec) + is changed to size_t, to match with ANSI C string + functions. + + * t1afm.c (t1_get_index): Ditto. + + * test_afm.c (dummy_get_index): Ditto. + + * afmparse.c (afm_parser_read_vals): To call + AFM_ParserRec.get_index, the length of token + `len' is cast to size_t. + +2009-07-31 suzuki toshiya + + cid: Fix some data types mismatching with their sources. + + * src/cid/cidparse.c (cid_parser_new): The types of + `read_len' and `stream_len' are matched to + FT_Stream->size. Unrequired cast is removed. + +2009-07-31 suzuki toshiya + + cff: Fix for unused variable `rest'. + + * src/cff/cffparse.c (cff_parse_real): Insert + FT_UNUSED() to hide the unused variable warning. + +2009-07-31 suzuki toshiya + + cff: Fix some data types mismatching with their sources. + + * src/cff/cffgload.c (cff_slot_load): The types of + `top_upm' and `sub_upm' are matched with + CFF_FontRecDict->units_per_em. + + * src/cff/cffobjs.c (cff_size_select): Ditto. + (cff_size_request): Ditto. + +2009-07-31 suzuki toshiya + + bdf: Fix some data types mismatching with their sources. + + * bdflib.c (_bdf_list_ensure): The type of `num_items' + is matched with _bdf_list_t.used. Also the types of + `oldsize', `newsize', `bigsize' are matched too. + (_bdf_readstream): `cursor' is used as an offset to + the pointer, it should be typed as FT_Offset. Also + the types of `bytes', `start', `end', `avail' are matched. + + * bdfdrivr.c: The type of BDF_CMap->num_encodings is + matched with FT_CMap->clazz->size. + (bdf_cmap_char_index): The types of `min', `max', `mid' + are matched with BDF_CMap->num_encodings. The type of + `result' is matched with encoding->glyph. + (bdf_cmap_char_next): Ditto, the type of `code' is + matched with BDF_encoding_el.enc. + (bdf_interpret_style): The type of `lengths' is changed + to size_t, to take the value by ft_strlen(). Also the + types of `len', `nn', `mm' are matched. + +2009-07-31 suzuki toshiya + + sfnt: Count the size of the memory object by ptrdiff_t. + + * src/sfnt/ttbdf.c (tt_face_find_bdf_prop): The type of + `peroperty_len' is changed from FT_UInt to FT_Offset, + to match with size_t, which is appropriate type for the + object in the memory buffer. + +2009-07-31 suzuki toshiya + + lzw: Count the size of the memory object by ptrdiff_t. + + * src/lzw/ftzopen.h: The types of FT_LzwState->{buf_total, + stack_size} are changed from FT_UInt to FT_Offset, to match + with size_t, which is appropriate type for the object in + the memory buffer. + + * src/lzw/ftzopen.c (ft_lzwstate_stack_grow): The types of + `old_size' and `new_size' are changed from FT_UInt to + FT_Offset, to match with size_t, which is appropriate type + for the object in the memory buffer. + +2009-07-31 suzuki toshiya + + otvalid: Count the table size on memory by ptrdiff_t. + + * src/otvalid/otvgpos.c (otv_ValueRecord_validate): + Change the type of table size from FT_UInt to + FT_PtrDist because it is calculated by the memory + addresses. + +2009-07-31 suzuki toshiya + + otvalid: Prevent an overflow by GPOS/GSUB 32b-bit offset. + + * src/otvalid/otvgpos.c (otv_ExtensionPos_validate): + Extend ExtensionOffset from FT_UInt to FT_ULong, to + cover 32-bit offset on 16-bit platform. + + * src/otvalid/otvgsub.c (otv_ExtensionSubst_validate): + Ditto. + +2009-07-31 suzuki toshiya + + ftobjs.c: Prevent an overflow in glyph index handling. + + * src/base/ftobjs.c (FT_Face_GetCharsOfVariant): + Improve the cast in comparison to avoid the truncation. + +2009-07-31 suzuki toshiya + + Improve the variable types in raccess_make_file_name(). + + * src/base/ftrfork.c (raccess_make_file_name): + Change the type of cursor variable `tmp' to const char*, + to prevent the unexpected modification of original pathname. + (raccess_make_file_name): Change the type of new_length + to size_t. + +2009-07-31 suzuki toshiya + + ftpatent.c: Fix for unused variable `error'. + + * src/base/ftpatent.c (_tt_check_patents_in_range): + Fix warning for unused variable `error'. + +2009-07-31 suzuki toshiya + + type1: Check invalid string longer than PostScript limit. + + * src/type1/t1afm.c (t1_get_index): Check invalid string + which exceeds the limit of PostScript string/name objects. + +2009-07-31 suzuki toshiya + + gzip: Use FT2 zcalloc() & zfree() in ftgzip.c by default. + + * src/gzip/ftgzip.c (zcalloc, zcfree): Disable all + zcalloc() & zfree() by zlib in zutil.c, those in + ftgzip.c by FT2 are enabled by default. To use + zlib zcalloc() & zfree(), define USE_ZLIB_ZCALLOC. + See discussion: + http://lists.gnu.org/archive/html/freetype-devel/2009-02/msg00000.html + +2009-07-31 suzuki toshiya + + gzip: Distinguish PureC from TurboC on MSDOS. + + * src/gzip/zutil.c (zcalloc, zcfree): Enable only for + MSDOS platform. + +2009-07-31 suzuki toshiya + + gxvalid: Insert PureC pragma to allow unevaluated variables. + + * builds/atari/ATARI.H: Insert PureC pragma not to + warn against set-but-unevaluated variable in gxvalid + module. + +2009-07-31 suzuki toshiya + + gxvalid: Pass the union by the pointer instead of the value. + + * src/gxvalid/gxvcommn.h: + - Declare new type `GXV_LookupValueCPtr'. + - Update the type of the 2nd argument to pass GXV_LookupValueDesc + data to the function prototyped as GXV_Lookup_Value_Validate_Func, + from GXV_LookupValueDesc to GXV_LookupValueCPtr. + - Likewise for the function prototyped as + GXV_Lookup_Fmt4_Transit_Func. + + - Declare new type `GXV_StateTable_GlyphOffsetCPtr'. + - Update the type of the 3rd argument to pass + GXV_StateTable_GlyphOffsetDesc data to the function prototyped + as GXV_StateTable_Entry_Validate_Func, from + GXV_StateTable_GlyphOffsetDesc to GXV_StateTable_GlyphOffsetCPtr. + + - Declare new type `GXV_XStateTable_GlyphOffsetCPtr'. + - Update the type of the 3rd argument to pass + GXV_XStateTable_GlyphOffsetDesc data to the function prototyped + as GXV_XStateTable_Entry_Validate_Func, + from GXV_XStateTable_GlyphOffsetDesc + to GXV_XStateTable_GlyphOffsetCPtr. + + * src/gxvalid/gxvcommn.c (gxv_LookupTable_fmt0_validate, + gxv_XClassTable_lookupval_validate, + gxv_XClassTable_lookupfmt4_transit): + Update from GXV_LookupValueDesc to GXV_LookupValueCPtr. + + * src/gxvalid/gxvbsln.c (gxv_bsln_LookupValue_validate, + gxv_bsln_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvjust.c + (gxv_just_pcTable_LookupValue_entry_validate, + gxv_just_classTable_entry_validate, + gxv_just_wdcTable_LookupValue_validate): Ditto. + + * src/gxvalid/gxvkern.c + (gxv_kern_subtable_fmt1_entry_validate): Ditto. + + * src/gxvalid/gxvlcar.c (gxv_lcar_LookupValue_validate, + gxv_lcar_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvopbd.c (gxv_opbd_LookupValue_validate, + gxv_opbd_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvprop.c (gxv_prop_LookupValue_validate, + gxv_prop_LookupFmt4_transit): Ditto. + + * src/gxvalid/gxvmort4.c + (gxv_mort_subtable_type4_lookupval_validate): Ditto. + + * src/gxvalid/gxvmort0.c + (gxv_mort_subtable_type0_entry_validate): Update + from GXV_StateTable_GlyphOffsetDesc + to GXV_StateTable_GlyphOffsetCPtr. + + * src/gxvalid/gxvmort1.c + (gxv_mort_subtable_type1_entry_validate): Ditto. + + * src/gxvalid/gxvmort2.c + (gxv_mort_subtable_type2_entry_validate): Ditto. + + * src/gxvalid/gxvmort5.c + (gxv_mort_subtable_type5_entry_validate): Ditto. + + * src/gxvalid/gxvmorx2.c + (gxv_morx_subtable_type2_entry_validate): Ditto. + + * src/gxvalid/gxvmorx5.c + (gxv_morx_subtable_type5_entry_validate): Ditto. + + * src/gxvalid/gxvmorx1.c + (gxv_morx_subtable_type1_entry_validate): Ditto. + (gxv_morx_subtable_type1_LookupValue_validate, + gxv_morx_subtable_type1_LookupFmt4_transit): + Update from GXV_LookupValueDesc to GXV_LookupValueCPtr. + + * src/gxvalid/gxvmorx0.c + (gxv_morx_subtable_type0_entry_validate): Update + from GXV_XStateTable_GlyphOffsetDesc + to GXV_XStateTable_GlyphOffsetCPtr. + +2009-07-29 Fabrice Bellet + + Fix Redhat bugzilla #513582 and Savannah bug #26849. + + * src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP) : Fix + aliasing bug. + +2009-07-19 Werner Lemberg + + Document recent library changes. + + * docs/CHANGES: Do it. + +2009-07-17 Werner Lemberg + + Fix Savannah bug #23786. + + * src/truetype/ttobjs.c (tt_size_init_bytecode): Don't reset x_ppem + and y_ppem. Otherwise the `*_CVT_Stretched' functions in ttinterp.c + get never called. + An anonymous guy suggested this change on Savannah, and it seems to + be the right solution. + +2009-07-15 Werner Lemberg + + * docs/release: Updated. + +2009-07-15 Werner Lemberg + + README.CVS -> README.git + + * README.CVS: Renamed to... + * README.git: This. + Updated. + +2009-07-15 suzuki toshiya + + Borland C++ compiler patch proposed by Mirco Babin. + http://lists.gnu.org/archive/html/freetype/2009-07/msg00016.html. + + * builds/exports.mk: Delete unused flags, CCexe_{CFLAGS,LDFLAGS}. + Fix APINAMES_C and APINAMES_EXE pathnames to reflect the platform + specific pathname syntax. + * builds/compiler/bcc.mk: Remove unused flag, CCexe_LDFLAGS. + Define TE = `-e' separately (bcc32 cannot specify the pathname of + binary executable by T = `-o'). + Extend the large page size in linking freetype.lib. + Add extra CLEAN target to delete bcc specific temporary files. + * builds/compiler/bcc-dev.mk: Ditto. + +2009-07-14 Werner Lemberg + + Fix Savannah bug #27026. + + * builds/win32/vc2005/freetype.sln: Use correct version number. + +2009-07-12 suzuki toshiya + + Add a script to check the undefined and unused trace macros. + + * src/tools/chktrcmp.py: A script to check trace_XXXX macros + that are used in C source but undefined in fttrace.h, or + defined in fttrace.h but unused in C sources. See + http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00013.html. + * docs/DEBUG: Mention on chktrcmp.py. + * docs/release: Ditto. + +2009-07-09 Werner Lemberg + + [ftraster] Make it compile again with -D_STANDALONE_. + + * src/raster/ftraster.c [_STANDALONE_]: Define + FT_CONFIG_STANDARD_LIBRARY_H. + Include `string.h'. + Don't include `rastpic.h'. + Define FT_DEFINE_RASTER_FUNCS. + +2009-07-09 suzuki toshiya + + smooth: Check glyph size by width/height, instead of pitch/height. + Suggested by der Mouse . + + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Improve + the check for too large glyph. Replace the pair of `pitch' and + `height' by the pair of `width' and `height'. `pitch' cannot + be greater than `height'. The required is checking the product + `pitch' * `height' <= FT_ULONG_MAX, but we use cheap checks for + the realistic case only. + +2009-07-09 suzuki toshiya + + Register 2 missing trace components, t1afm and ttbdf. + + * include/freetype/internal/fttrace.h: Add FT_TRACE_DEF( t1afm ) + and FT_TRACE_DEF( ttbdf ). See + http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00013.html + +2009-07-09 suzuki toshiya + + Register a trace component for ftgloadr.c. + + * include/freetype/internal/fttrace.h: Add FT_TRACE_DEF( gloader ). + The macro `trace_gloader' was already used in the initial version + on 2002-02-24. + +2009-07-08 suzuki toshiya + + Prevent the overflows by a glyph with too many points or contours. + The bug is reported by Boris Letocha . See + http://lists.gnu.org/archive/html/freetype-devel/2009-06/msg00031.html + http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00002.html + + * include/freetype/ftimage.h (FT_OUTLINE_CONTOURS_MAX, + FT_OUTLINE_POINTS_MAX): New macros to declare the maximum + values of FT_Outline.{n_contours,n_points}. + * src/base/ftgloadr.c (FT_GlyphLoader_CheckPoints): Check the + total numbers of points and contours cause no overflows in + FT_Outline.{n_contours,n_points}. + + * include/freetype/internal/ftgloadr.h (FT_GLYPHLOADER_CHECK_P, + FT_GLYPHLOADER_CHECK_C): Compare the numbers of points and + contours as unsigned long number, instead of signed int, to + prevent the overflows on 16-bit systems. + +2009-07-05 Bram Tassyns + + Improve compatibility to Acroread. + This fixes Savannah bug #26944. + + * src/cff/cffload.c (cff_charset_compute_cids): For multiple GID to + single CID mappings, make the lowest value win. + +2009-06-28 suzuki toshiya + + ftpatent: Fix a bug by wrong usage of service->table_info(). + http://lists.gnu.org/archive/html/freetype-devel/2008-12/msg00039.html + + * include/freetype/internal/services/svsfnt.h: Extend + FT_SFNT_TableInfoFunc() to take new argument to obtain the offset + to the specified table. + * src/sfnt/sfdriver.c (sfnt_table_info): Extend to return the + table-offset to the caller function. + * src/base/ftpatent.c (_tt_check_patents_in_table): Use new + service->table_info(). + * src/base/ftobjs.c (FT_Sfnt_Table_Info): Synchronize to new + service->table_info(). + +2009-06-28 Werner Lemberg + + [psaux, cff] Protect against nested `seac' calls. + + * include/freetype/internal/psaux.h (T1_Decoder), src/cff/cffgload.h + (CFF_Decoder): Add `seac' boolean variable. + + * src/cff/cffgload.c (cff_operator_seac), src/psaux/t1decode.c + (t1operator_seac): Use it. + +2009-06-28 Werner Lemberg + + Thinko. + + * src/psaux/t1decode.c (t1operator_seac) + [FT_CONFIG_OPTION_INCREMENTAL]: Test for existence of incremental + interface. + +2009-06-28 Werner Lemberg + + * devel/ftoption.h [FT_CONFIG_OPTION_INCREMENTAL]: Define. + +2009-06-27 suzuki toshiya + + Add tools to preprocess the source files for AtariST PureC. + + * builds/atari/deflinejoiner.awk: New file to filter C source files + for broken C preprocessor of PureC compiler. + + * builds/atari/gen-purec-patch.sh: New file to generate a patch set + for PureC, by using deflinejoiner.awk. + +2009-06-27 suzuki toshiya + + Keep existing modules.cfg in the building tree. + + * configure: If `configure' is executed outside of the source tree, + an existing `modules.cfg' file in the build directory should be + kept, not overwritten by the version in the source tree. + +2009-06-27 suzuki toshiya + + Filter --srcdir= option before invoking builds/unix/configure. + + * configure: If builds/unix/configure is invoked with --srcdir + option, the option should take `builds/unix' directory instead of + the top source directory. Thus the configure script in the top + directory should modify the --srcdir= option if + `builds/unix/configure' is invoked. + +2009-06-27 suzuki toshiya + + Improve configure.raw for cross-building on exe-suffixed systems. + + * builds/unix/configure.raw: Fix a bug in sed script to extract + native suffix for binary executables, patch by Peter Breitenlohner. + http://lists.gnu.org/archive/html/freetype-devel/2009-04/msg00036.html + +2009-06-26 Werner Lemberg + + [truetype] Remove TT_SubGlyphRec. + + * src/truetype/ttobjs.h (TT_SubGlyphRec): Removed, unused. + +2009-06-26 Werner Lemberg + + * */*: For warning messages, replace FT_ERROR with FT_TRACE0. + + FT_ERROR is now used only if a function produces a non-zero `error' + value. + + Formatting, improving and harmonizing debug strings. + +2009-06-25 Werner Lemberg + + Provide version information better. + + * src/base/ftinit.c (FT_Init_FreeType): Don't set version here + but... + * src/base/ftobjs.c (FT_New_Library): Here. + +2009-06-22 Werner Lemberg + + Use 16.16 format while parsing Type 1 charstrings. + This fixes Savannah bug #26867. + + Previously, only integers have been used which can lead to serious + rounding errors. + + However, fractional values are only used internally; after the + charstrings (of either Type 1 or 2) have been processed, the + resulting coordinates get rounded to integers currently -- before + applying scaling. This should be fixed; at the same time a new load + flag should be introduced, to be used in combination with + FT_LOAD_NO_SCALE, which indicates that font units are returned in + 16.16 format. Similarly, the incremental interface should be + extended to allow fractional values for metrics. + + * include/freetype/internal/psaux.h (T1_BuilderRec): Remove `shift' + field. + * include/freetype/internal/pshints.h (T1_Hints_SetStemFunc, + T1_Hints_SetStem3Func): Use FT_Fixed for coordinates. + + * src/psaux/psobjs.c: Include FT_INTERNAL_CALC_H. + (t1_build_add_point): Always convert fixed to integer. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): + Use 16.16 format everywhere (except for large integers followed by a + `div'). + [CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS]: Remove #ifdef and activate + code uncoditionally. + Add support for random numbers and update remaining code + accordingly; this should work now. + (t1_operator_seac): Updated. + * src/psaux/pshrec.c: Include FT_INTERNAL_CALC_H. + (ps_hints_t1stem3, t1_hints_stem): Updated. + + * src/cid/cidgload.c: Include FT_INTERNAL_CALC_H. + (cid_load_glyph) [FT_CONFIG_OPTION_INCREMENTAL], + (cid_face_compute_max_advance, cid_slot_load_glyph): Updated. + + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String) + [FT_CONFIG_OPTION_INCREMENTAL], (T1_Get_Advances, T1_Load_Glyph): + Updated. + * src/type1/t1load.c: Include FT_INTERNAL_CALC_H. + * src/type1/t1objs.c (T1_Face_Init): Updated. + +2009-06-21 Werner Lemberg + + * src/pshinter/pshrec.c: Use PSH_Err_Ok. + +2009-06-21 Werner Lemberg + + Code beautification. + + * src/type1/t1load.c (FT_INT_TO_FIXED): Removed. + Replace everywhere with INT_TO_FIXED. + (FT_FIXED_TO_INT): Move to ... + * include/freetype/internal/ftcalc.h (FIXED_TO_INT): Here. + Update all users. + +2009-06-20 Werner Lemberg + + Remove unused variables. + + * include/freetype/internal/psaux.h (T1_BuilderRec), + src/cff/cffgload.h (CFF_Builder): Remove `last'. + Update all users. + +2009-06-20 Werner Lemberg + + [psaux] Check large integers while parsing charstrings. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Large + integers must be followed by a `div' operator. + +2009-06-20 Werner Lemberg + + [cff] Revert last change. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): Do it. + Next time, don't confuse Type 2 charstring opcodes with TOP DICT + values... + +2009-06-20 Werner Lemberg + + * src/autofit/aflatin.c (af_latin_metrics_check_digits): Fix + compiler warning. + +2009-06-20 Werner Lemberg + + * builds/compiler/gcc.mk (CFLAGS): Use -O3, not -O6. + +2009-06-19 Werner Lemberg + + [cff] Fix handling of reserved byte 0xFF. + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): Abort if byte + 0xFF is encountered. + +2009-06-19 Werner Lemberg + + Improve debug messages for Type1 charstrings. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Emit newlines + after instructions. + Prettify output. + +2009-06-19 Werner Lemberg + + More ftgray fixes for FT_STATIC_RASTER. + Problems reported by suyu@cooee.cn. + + * src/smooth/ftgrays.c (gray_move_to, gray_raster_render): Use + RAS_VAR. + +2009-06-18 Werner Lemberg + + * docs/CHANGES: Updated. + +2009-06-18 Werner Lemberg + + Fix B/W rasterization of subglyphs with different drop-out modes. + + Normally, the SCANMODE instruction (if present) to set the drop-out + mode in a TrueType font is located in the `prep' table only and thus + valid for all glyphs. However, there are fonts like `pala.ttf' + which additionally contain this instruction in the hinting code of + some glyphs (but not all). As a result it can happen that a + composite glyph needs multiple drop-out modes for its subglyphs + since the rendering state gets reset for each subglyph. + + FreeType collects the hinted outlines from all subglyphs, then it + sends the data to the rasterizer. It also sends the drop-out mode + -- after hinting has been applied -- and here is the error: It sends + the drop-out mode of the last subglyph only; drop-out modes of all + other subglyphs are lost. + + This patch fixes the problem; it adds a second, alternative + mechanism to pass the drop-out mode: For each contour, the + rasterizer now checks the first `tags' array element. If bit 2 is + set, bits 5-7 contain the contour's drop-out mode, overriding the + global drop-out mode. + + * include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro. + + * src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in + `tags[0]'. + + * src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom): + Use bits 3-5 instead of 0-2. + (New_Profile): Set the drop-out mode in the profile's `flags' field. + (Decompose_Curve): Check `tags[0]' and set `dropOutControl' if + necessary. + (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out + mode. + +2009-06-16 Werner Lemberg + + Improve scan conversion rules 4 and 6. + + Two new constraints are introduced to better identify a `stub' -- a + concept which is only vaguely described in the OpenType + specification. The old code was too rigorous and suppressed more + pixel than it should. + + . The intersection of the two profiles with the scanline is less + than a half pixel. Code related to this was already present in + the sources but has been commented out. + + . The endpoint of the original contour forming a profile has a + distance (`overshoot') less than half a pixel to the scanline. + + Note that the two additional conditions fix almost all differences + to the Windows rasterizer, but some problematic cases remain. + + * src/raster/ftraster.c (Overshoot_Top, Overshoot_Bottom): New + macros for the `flags' field in the `TProfile' structure. + (IS_BOTTOM_OVERSHOOT, IS_TOP_OVERSHOOT): New macros. + (New_Profile, End_Profile): Pass overshoot flag as an argument and + set it accordingly. + Update callers. + (Vertical_Sweep_Drop, Horizontal_Sweep_Drop): Implement the two new + constraints. + +2009-06-11 Werner Lemberg + + Increase precision for B/W rasterizer. + + * src/raster/ftraster.c (Set_High_Precision): Add two more bits to + the precision. This corrects rendering of some small glyphs, for + example, glyph `xi' in verdana.ttf at 13 ppem. Testing with ftbench + on my GNU/Linux box I don't see a performance degradation. + +2009-06-08 Michael Zucchi + + Handle FT_STROKER_LINECAP_BUTT. + This fixes Savannah bug #26757. + + * src/base/ftstroke.c (ft_stroker_cap): Implement it. + +2009-06-07 Harald Fernengel + + Fix some potential out-of-memory crashes. + + * src/base/ftobjs.c (ft_glyphslot_done): Check `slot->internal'. + * src/base/ftstream.c (FT_Stream_ReleaseFrame): Check `stream'. + * src/truetype/ttinterp.c (TT_New_Context): Avoid double-free of + `exec' in case of failure. + +2009-06-07 Werner Lemberg + + Simplify math. + Suggested by Alexei Podtelezhnikov . + + * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): Do it. + +2009-06-04 Werner Lemberg + + Preparation for fixing scan conversion rules 4 and 6. + + * src/raster/ftraster.c (TFlow): Replace enumeration with... + (Flow_Up): This macro. + (TProfile): Replace `flow' member with `flags' bit field. + Update all affected code. + +2009-05-29 James Cloos + + Enable autohinting for glyphs rotated by multiples of 90°. + + * src/base/ftobjs.c (FT_Load_Glyph): Alter check for permitted + matrices to allow rotations by multiples of 90°, not only unrotated, + possibly slanted matrices. + +2009-05-28 Werner Lemberg + + Remove compiler warning. + Reported by Krzysztof Kowalczyk . + + * src/autofit/aflatin2.c (af_latin2_hint_edges): Move declaration of + `n_edges' into `#if' block. + +2009-05-28 Werner Lemberg + + Make compilation work with FT_CONFIG_OPTION_USE_ZLIB not defined. + Reported by Krzysztof Kowalczyk . + + * src/pcf/pcfdrivr.c (PCF_Face_Init) [!FT_CONFIG_OPTION_USE_ZLIB]: + Make it work. + Simplify #ifdef logic. + +2009-05-22 Werner Lemberg + + Improve b/w rasterizer. + Problem reported by Krzysztof Kotlenga . + + * src/raster/raster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): For smart drop-out mode, if + intersections are equally distant relative to next pixel center, + select the left pixel, not the right one. + +2009-05-19 Werner Lemberg + + Fix Savannah bug #26600. + + * src/type42/t42parse.c (t42_load_keyword): Handle + T1_FIELD_LOCATION_FONT_EXTRA. + +2009-04-30 Werner Lemberg + + Document recent changes to ftview. + + * docs/CHANGES: Do it. + +2009-04-27 Werner Lemberg + + autohinter: Don't change digit widths if all widths are the same. + This fixes FreeDesktop bug #21197. + + * src/autofit/afglobal.c (AF_DIGIT): New macro. + (af_face_globals_compute_script_coverage): Mark ASCII digits in + `glyph_scripts' array. + (af_face_globals_get_metrics): Updated. + (af_face_globals_is_digit): New function. + * src/autofit/afglobal.h: Updated. + (AF_ScriptMetricsRec): Add `digits_have_same_width' flag. + + * src/autofit/aflatin.c: Include FT_ADVANCES_H. + (af_latin_metrics_check_digits): New function. + (af_latin_metrics_init): Use it. + * src/autofit/aflatin.h: Updated. + * src/autofit/afcjk.c (af_cjk_metrics_init): Updated. + + * src/autofit/aflatin2.c: Similar changes as with aflatin.c. + + * src/autofit/afloader.c (af_loader_load_g): Test digit width. + + * docs/CHANGES: Document it. + +2009-04-26 Werner Lemberg + + Make ftgrays compile with _STANDALONE_ and FT_STATIC_RASTER again. + Problems reported by suyu@cooee.cn. + + * src/smooth/ftgrays.c (FT_DEFINE_OUTLINE_FUNCS, + FT_DEFINE_RASTER_FUNCS) [_STANDALONE_]: Define. + [!_STANDALONE_]: Include ftspic.h only here. + (ras): Define/declare after definition of `TWorker'. + Use `RAS_VAR_' where necessary. + +2009-04-21 Karl Berry + + Fix AC_CHECK_FT2. + + * builds/unix/freetype2.m4: Only check PATH for freetype-config if + we did not already find it from a prefix option. + +2009-04-05 Oran Agra + + Add #error to modules and files that do not support PIC yet. + + When FT_CONFIG_OPTION_PIC is defined the following files will + create #error: + * src/bdf/bdfdrivr.h + * src/cache/ftcmanag.c + * src/cid/cidriver.h + * src/gxvalid/gxvmod.h + * src/gzip/ftgzip.c + * src/lzw/ftlzw.c + * src/otvalid/otvmod.h + * src/pcf/pcfdrivr.h + * src/pfr/pfrdrivr.h + * src/psaux/psauxmod.h + * src/type1/t1driver.h + * src/type42/t42drivr.h + * src/winfonts/winfnt.h + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in autofit module. + + * include/freetype/internal/autohint.h add macros to init + instances of FT_AutoHinter_ServiceRec. + + * src/autofit/afmodule.h declare autofit_module_class + using macros from ftmodapi.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/autofit/afmodule.c when FT_CONFIG_OPTION_PIC is defined + af_autofitter_service and autofit_module_class structs + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from afpic.h in order to access them. + + * src/autofit/aftypes.h add macros to init and declare + instances of AF_ScriptClassRec. + + * src/autofit/afcjk.h declare af_cjk_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/afcjk.c when FT_CONFIG_OPTION_PIC is defined + af_cjk_script_class struct will have function to init it instead of + being allocated in the global scope. + + * src/autofit/afdummy.h declare af_dummy_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/afdummy.c when FT_CONFIG_OPTION_PIC is defined + af_dummy_script_class struct will have function to init it instead of + being allocated in the global scope. + + * src/autofit/afindic.h declare af_indic_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/afindic.c when FT_CONFIG_OPTION_PIC is defined + af_indic_script_class struct will have function to init it instead of + being allocated in the global scope. + + * src/autofit/aflatin.h declare af_latin_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/aflatin.c when FT_CONFIG_OPTION_PIC is defined + af_latin_script_class struct will have function to init it instead of + being allocated in the global scope. + Change af_latin_blue_chars to be PIC-compatible by being a two + dimentional array rather than array of pointers. + + + * src/autofit/aflatin2.h declare af_latin2_script_class + using macros from aftypes.h, + when FT_CONFIG_OPTION_PIC is defined init function will be declared. + * src/autofit/aflatin2.c when FT_CONFIG_OPTION_PIC is defined + af_latin2_script_class struct will have function to init it instead of + being allocated in the global scope. + Change af_latin2_blue_chars to be PIC-compatible by being a two + dimentional array rather than array of pointers. + + * src/autofit/afglobal.c when FT_CONFIG_OPTION_PIC is defined + af_script_classes array initialization was moved to afpic.c and + is later refered using macros defeined in afpic.h. + + New Files: + * src/autofit/afpic.h declare struct to hold PIC globals for autofit + module and macros to access them. + * src/autofit/afpic.c implement functions to allocate, destroy and + initialize PIC globals for autofit module. + + * src/autofit/autofit.c add new file to build: afpic.c. + * src/autofit/jamfile add new files to FT2_MULTI build: afpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in pshinter module. + + * include/freetype/internal/pshints.h add macros to init + instances of PSHinter_Interface. + + * src/pshinter/pshmod.h declare pshinter_module_class + using macros from ftmodapi.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/pshinter/pshmod.c when FT_CONFIG_OPTION_PIC is defined + pshinter_interface and pshinter_module_class structs + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from pshpic.h in order to access them. + + New Files: + * src/pshinter/pshpic.h declare struct to hold PIC globals for pshinter + module and macros to access them. + * src/pshinter/pshpic.c implement functions to allocate, destroy and + initialize PIC globals for pshinter module. + + * src/pshinter/pshinter.c add new file to build: pshpic.c. + * src/pshinter/jamfile add new files to FT2_MULTI build: pshpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in psnames module. + + * include/freetype/internal/services/svpscmap.h add macros to init + instances of FT_Service_PsCMapsRec. + + * src/psnames/psmodule.h declare psnames_module_class + using macros from ftmodapi.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/psnames/psmodule.c when FT_CONFIG_OPTION_PIC is defined + pscmaps_interface and pscmaps_services structs + and psnames_module_class array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from pspic.h in order to access them. + + New Files: + * src/psnames/pspic.h declare struct to hold PIC globals for psnames + module and macros to access them. + * src/psnames/pspic.c implement functions to allocate, destroy and + initialize PIC globals for psnames module. + + * src/psnames/psnames.c add new file to build: pspic.c. + * src/psnames/jamfile add new files to FT2_MULTI build: pspic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in raster renderer. + + * src/raster/ftrend1.h declare ft_raster1_renderer_class + and ft_raster5_renderer_class + using macros from ftrender.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/smooth/ftrend1.c when FT_CONFIG_OPTION_PIC is defined + ft_raster1_renderer_class and ft_raster5_renderer_class structs + will have functions to init or create and destroy them + instead of being allocated in the global scope. + Macros will be used from rastpic.h in order to access + ft_standard_raster from the pic_container (allocated in ftraster.c). + In ft_raster1_render when PIC is enabled, the last letter of + module_name is used to verfy the renderer class rather than the + class pointer. + + * src/raster/ftraster.c when FT_CONFIG_OPTION_PIC is defined + ft_standard_raster struct will have function to init it + instead of being allocated in the global scope. + + New Files: + * src/raster/rastpic.h declare struct to hold PIC globals for raster + renderer and macros to access them. + * src/raster/rastpic.c implement functions to allocate, destroy and + initialize PIC globals for raster renderer. + + * src/raster/raster.c add new file to build: rastpic.c. + * src/raster/jamfile add new files to FT2_MULTI build: rastpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in smooth renderer. + + * src/smooth/ftsmooth.h declare ft_smooth_renderer_class, + ft_smooth_lcd_renderer_class and ft_smooth_lcd_v_renderer_class + using macros from ftrender.h, + when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/smooth/ftsmooth.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + ft_smooth_renderer_class, ft_smooth_lcd_renderer_class + and ft_smooth_lcd_v_renderer_class + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from ftspic.h in order to access + ft_grays_raster from the pic_container (allocated in ftgrays.c). + + * src/smooth/ftgrays.h include FT_CONFIG_CONFIG_H + * src/smooth/ftgrays.c when FT_CONFIG_OPTION_PIC is NOT defined + func_interface was moved from gray_convert_glyph_inner function + to the global scope. + When FT_CONFIG_OPTION_PIC is defined + func_interface and ft_grays_raster structs + will have functions to init them + instead of being allocated in the global scope. + And func_interface will be allocated on the stack of + gray_convert_glyph_inner. + + New Files: + * src/smooth/ftspic.h declare struct to hold PIC globals for smooth + renderer and macros to access them. + * src/smooth/ftspic.c implement functions to allocate, destroy and + initialize PIC globals for smooth renderer. + + * src/smooth/smooth.c add new file to build: ftspic.c. + * src/smooth/jamfile add new files to FT2_MULTI build: ftspic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in cff driver. + + * include/freetype/internal/services/svcid.h add macros to init + instances of FT_Service_CIDRec. + * include/freetype/internal/services/svpsinfo.h add macros to init + instances of FT_Service_PsInfoRec. + + * src/cff/cffcmap.h declare cff_cmap_encoding_class_rec + and cff_cmap_unicode_class_rec using macros from + ftobjs.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/cff/cffcmap.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + cff_cmap_encoding_class_rec and cff_cmap_unicode_class_rec + will have functions to init or create and destroy them + instead of being allocated in the global scope. + + * src/cff/cffdrivr.h declare cff_driver_class using macros from + ftdriver.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/cff/cffdrivr.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + cff_service_glyph_dict, cff_service_ps_info, cff_service_ps_name + cff_service_get_cmap_info, cff_service_cid_info, cff_driver_class, + and cff_services array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from cffpic.h in order to access them + from the pic_container. + Use macros from cffpic.h in order to access the + structs allocated in cffcmap.c + + * src/cff/cffobjs.c Use macros from cffpic.h in order to access the + structs allocated in cffcmap.c + + * src/cff/parser.c when FT_CONFIG_OPTION_PIC is defined + implement functions to create and destroy cff_field_handlers array + instead of being allocated in the global scope. + And macros will be used from cffpic.h in order to access it + from the pic_container. + + New Files: + * src/cff/cffpic.h declare struct to hold PIC globals for cff + driver and macros to access them. + * src/cff/cffpic.c implement functions to allocate, destroy and + initialize PIC globals for cff driver. + + * src/cff/cff.c add new file to build: cffpic.c. + * src/cff/jamfile add new files to FT2_MULTI build: cffpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in sfnt driver. + + * include/freetype/internal/services/svbdf.h add macros to init + instances of FT_Service_BDFRec. + * include/freetype/internal/services/svgldict.h add macros to init + instances of FT_Service_GlyphDictRec. + * include/freetype/internal/services/svpostnm.h add macros to init + instances of FT_Service_PsFontNameRec. + * include/freetype/internal/services/svsfnt.h add macros to init + instances of FT_Service_SFNT_TableRec. + * include/freetype/internal/services/svttcmap.h add macros to init + instances of FT_Service_TTCMapsRec. + * include/freetype/internal/sfnt.h add macros to init + instances of SFNT_Interface. + + * src/sfnt/sfdriver.h declare sfnt_module_class using macros from + ftmodapi.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/sfnt/sfdriver.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + sfnt_service_sfnt_table, sfnt_service_glyph_dict, sfnt_service_ps_name + tt_service_get_cmap_info, sfnt_service_bdf, sfnt_interface, + sfnt_module_class, and sfnt_services array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from sfntpic.h in order to access them + from the pic_container. + + * src/sfnt/ttcmap.h add macros to init + instances of TT_CMap_ClassRec. + * src/sfnt/ttcmap.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + tt_cmap0_class_rec, tt_cmap2_class_rec, tt_cmap4_class_rec + tt_cmap6_class_rec, tt_cmap8_class_rec, tt_cmap10_class_rec, + tt_cmap12_class_rec, tt_cmap14_class_rec and tt_cmap_classes array + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from sfntpic.h in order to access them + from the pic_container. + The content of tt_cmap_classes is now described in the + new file 'ttcmapc.h'. + + New Files: + * src/sfnt/sfntpic.h declare struct to hold PIC globals for sfnt + driver and macros to access them. + * src/sfnt/sfntpic.c implement functions to allocate, destroy and + initialize PIC globals for sfnt driver. + * src/sfnt/ttcmapc.h describing the content of + tt_cmap_classes allocated in ttcmap.c + + * src/sfnt/sfnt.c add new file to build: sfntpic.c. + * src/sfnt/jamfile add new files to FT2_MULTI build: sfntpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support in truetype driver. + + * include/freetype/internal/services/svmm.h add macros to init + instances of FT_Service_MultiMastersRec. + * include/freetype/internal/services/svttglyf.h add macros to init + instances of FT_Service_TTGlyfRec. + + * src/truetype/ttdriver.h declare tt_driver_class using macros from + ftdriver.h, when FT_CONFIG_OPTION_PIC is defined create and destroy + functions will be declared. + * src/truetype/ttdriver.c when FT_CONFIG_OPTION_PIC is defined + the following structs: + tt_service_gx_multi_masters, tt_service_truetype_glyf, tt_driver_class + and tt_services array, + will have functions to init or create and destroy them + instead of being allocated in the global scope. + And macros will be used from ttpic.h in order to access them + from the pic_container. + * src/truetype/ttobjs.c change trick_names array to be + PIC-compatible by being a two dimentional array rather than array + of pointers. + + New Files: + * src/truetype/ttpic.h declare struct to hold PIC globals for truetype + driver and macros to access them. + * src/truetype/ttpic.c implement functions to allocate, destroy and + initialize PIC globals for truetype driver. + + * src/truetype/truetype.c add new file to build: ttpic.c. + * src/truetype/jamfile add new files to FT2_MULTI build: ttpic.c. + +2009-04-05 Oran Agra + + Position Independent Code (PIC) support and infrastructure in base. + + * include/freetype/config/ftoption.h add FT_CONFIG_OPTION_PIC + * include/freetype/internal/ftobjs.h Add pic_container member to + FT_LibraryRec. + Add macros to declare and init instances of FT_CMap_ClassRec. + Add macros to init instances of FT_Outline_Funcs and FT_Raster_Funcs. + Add macros to declare, allocate and initialize modules + (FT_Module_Class). + Add macros to declare, allocate and initialize renderers + (FT_Renderer_Class). + Add macro to init instances of FT_Glyph_Class. + Add macros to declare, allocate and initialize drivers + (FT_Driver_ClassRec). + * include/freetype/internal/ftpic.h new file to declare the + FT_PIC_Container struct and the functions to allocate and detroy it. + * include/freetype/internal/ftserv.h add macros to allocate and + destory arrays of FT_ServiceDescRec. + * include/freetype/internal/internal.h define macro to include + ftpic.h. + + New Files: + * src/base/ftpic.c implement functions to allocate and destory the + global pic_container. + * src/base/basepic.h declare struct to hold PIC globals for base and + macros to access them. + * src/base/basepic.c implement functions to allocate, destroy and + initialize PIC globals for base. + + * src/base/ftinit.c when FT_CONFIG_OPTION_PIC is defined implement + functions that allocate and destroy ft_default_modules according to + FT_CONFIG_MODULES_H in the pic_container instead of the global scope + and use macro from basepic.h to access it. + * src/base/ftobjs.c add calls to the functions that allocate and + destroy the global pic_container when the library is created and + destroyed. + + * src/base/jamfile add new files to FT2_MULTI build: + ftpic.c and basepic.c. + * src/base/ftbase.c add new files to build: + ftpic.c and basepic.c. + + * src/base/ftglyph.c when FT_CONFIG_OPTION_PIC is defined + ft_bitmap_glyph_class and ft_outline_glyph_class will be allocated + in the pic_container instead of the global scope and use macros from + basepic.h to access them. + * src/base/ftbbox.c allocate bbox_interface stract on the stack + instead of the global scope when FT_CONFIG_OPTION_PIC is defined. + * src/base/ftstroke.c access ft_outline_glyph_class allocated in + ftglyph.c via macros from basepic.h + +2009-04-05 Oran Agra + + Preparing changes in cff parser later needed for PIC version. + + * src/cff/cffload.c, src/cff/cffload.h, src/cff/cffobjs.c, + src/cff/cffparse.c, src/cff/cffparse.h: Add library pointer to + 'CFF_ParserRec' set by `cff_parser_init'. + Route library pointer from 'cff_face_init' to 'cff_subfont_load' + for `cff_parser_init'. + + * src/cff/cffparse.c (CFF_Field_Handler): Move it to... + * src/cff/cffparse.h: This file, to be used by other C files. + +2009-04-05 Oran Agra + + Minor change in ftstroke.c. + + * src/base/ftstroke.c (FT_StrokerRec): Replace `memory' member with + `library' needed for PIC version. + Update all callers. + +2009-04-04 Werner Lemberg + + ftnames.c -> ftsnames.c + + * src/base/ftnames.c: Rename to... + * src/base/ftsnames.c: This. + * src/base/Jamfile, src/base/rules.mk, src/base/ftbase.c: Updated. + +2009-04-04 Werner Lemberg + + Add support for cmap type 13. + + * devel/ftoption.h, include/freetype/config/ftoption.h + (TT_CONFIG_CMAP_FORMAT_13): New macro. + + * src/sfnt/ttcmap.c (TT_CMap13Rec, tt_cmap13_init, + tt_cmap13_validate, tt_cmap13_char_index, tt_cmap13_char_next, + tt_cmap13_get_info, tt_cmap13_char_map_def_binary, + tt_cmap14_class_rec): New functions and structures for cmap 13 + support. + (tt_cmap_classes): Register tt_cmap13_class_rec. + + * docs/CHANGES: Mention cmap 13 support. + +2009-04-01 Werner Lemberg + + Ignore empty contours in CFF glyphs. + + Problem reported by Albert Astals Cid . + + * src/cff/cffgload.c (cff_builder_close_contour): Synchronize with + t1_builder_close_contour. + +2009-03-21 Werner Lemberg + + Another redundant header inclusion. + + * src/truetype/ttgxvar.c: Fix Ghostscript Coverity issue #4041. + +2009-03-21 Werner Lemberg + + Remove redundant header inclusions. + + This covers many Ghostscript Coverity issues. + + * src/*: Do it. + +2009-03-21 Werner Lemberg + + Fix Ghostscript Coverity issue #3904. + + * src/truetype/ttgxvar.c (ft_var_readpackedpoints): Protect against + invalid values of `runcnt'. + +2009-03-20 Werner Lemberg + + Fix `make multi' run. + + * src/smooth/ftsmooth.h: Include FT_INTERNAL_DEBUG_H. + +2009-03-20 Werner Lemberg + + Fix Savannah bug #25923. + + * src/cache/ftccmap.c (FTC_CMAP_HASH): Fix typo. + +2009-03-20 Werner Lemberg + + Protect against too large glyphs. + + Problem reported by Tavis Ormandy . + + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Don't allow + `pitch' or `height' to be larger than 0xFFFF. + +2009-03-20 Werner Lemberg + Tavis Ormandy + + Fix validation for various cmap table formats. + + * src/sfnt/ttcmap.c (tt_cmap8_validate, tt_cmap10_validate, + tt_cmap12_validate): Check `length' correctly. + (tt_cmap_14_validate): Check `length' and `numMappings' correctly. + +2009-03-20 Werner Lemberg + + Protect against malformed compressed data. + + * src/lzw/ftzopen.c (ft_lzwstate_io): Test whether `state->prefix' is + zero. + +2009-03-20 Werner Lemberg + + Protect against invalid SID values in CFFs. + + Problem reported by Tavis Ormandy . + + * src/cff/cffload.c (cff_charset_load): Reject SID values larger + than 64999. + +2009-03-19 Vincent Richomme + + Update WinCE Visual C project files. + + * builds/wince/vc2005-ce/freetype.vcproj, + builds/wince/vc2008-ce/freetype.vcproj: Add missing base extension + files. + +2009-03-19 Werner Lemberg + + Remove unused Win32 code. + + * builds/wince/ftdebug.c: Remove code guarded with `!_WIN32_WCE'. + Since Win32 is handled separately this is no longer needed. + +2009-03-19 Vincent Richomme + + Make `gzip' module compile on WinCE. + + * src/gzip/zconf.h [_WIN32_WCE]: Define NO_ERRNO_H. + +2009-03-19 Werner Lemberg + + Remove unused WinCE code. + + * builds/win32/ftdebug.c: Remove code guarded with `_WIN32_WCE'. + Since WinCE is handled separately this is no longer needed. + +2009-03-16 Werner Lemberg + + docmaker: Don't ignore single-line code blocks. + + * src/tools/docmaker/content.py (DocBlock::_init__): Fix change from + 2009-01-31. + +2009-03-15 Steve Langasek + + Use __asm__ for declaring assembly instead of asm. + + * builds/unix/ftconfig.in (FT_MulFix_arm): Use __asm__ instead of + asm on arm, fixing a build failure on armel with -pedantic. + +2009-03-14 Werner Lemberg + + Fix valgrind warning. + + * src/sfnt/ttsbit0.c (tt_sbit_decoder_load_bit_aligned): Don't read + past the end of the frame. + +2009-03-12 Werner Lemberg + + * Version 2.3.9 released. + ========================= + + + Tag sources with `VER-2-3-9'. + +2009-03-12 Werner Lemberg + + * builds/unix/freetype2.in: Move @FT2_EXTRA_LIBS@ to `Libs.private'. + +2009-03-12 Werner Lemberg + + Fix some FreeType Coverity issues as reported for Ghostscript. + + * src/base/ftobjs.c (FT_New_Face, FT_New_Memory_Face): Initialize + `args.stream' (#3874, #3875). + (open_face_PS_from_sfnt_stream): Improve error management (#3786). + * src/base/ftmm.c (ft_face_get_mm_service): Fix check of `aservice' + (#3870). + * src/base/ftstroke.c (ft_stroke_border_get_counts): Remove dead + code (#3790). + * src/base/ftrfork.c (raccess_guess_apple_generic): Check error + value of `FT_Stream_Skip' (#3784). + + * src/type1/t1gload.c (T1_Load_Glyph): Check `size' before accessing + it (#3872) + + * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Check `face' before accessing + it (#3871). + * src/pcf/pcfread.c (pcf_get_metrics): Handle return value of + `pcf_get_metric' (#3789, #3782). + (pcf_get_properties): Use FT_STREAM_SKIP (#3783). + + * src/cache/ftcmanag.c (FTC_Manager_RegisterCache): Fix check of + `acache' (#3797) + + * src/cff/cffdrivr.c (cff_ps_get_font_info): Fix check of `cff' + (#3796). + * src/cff/cffgload.c (cff_decoder_prepare): Check `size' (#3795). + * src/cff/cffload.c (cff_index_get_pointers): Add comment (#3794). + + * src/bdf/bdflib.c (_bdf_add_property): Check `fp->value.atom' + (#3793). + (_bdf_parse_start): Add comment (#3792). + + * src/raster/ftraster.c (Finalize_Profile_Table): Check + `ras.fProfile' (#3791). + + * src/sfnt/ttsbit.c (Load_SBit_Image): Use FT_STREAM_SKIP (#3785). + + * src/gzip/ftgzip.c (ft_gzip_get_uncompressed_size): Properly ignore + seek error (#3781). + +2009-03-11 Michael Toftdal + + Extend CID service functions to handle CID-keyed CFFs as CID fonts. + + * include/freetype/ftcid.h (FT_Get_CID_Is_Internally_CID_keyed, + FT_Get_CID_From_Glyph_Index): New functions. + + * include/freetype/internal/services/svcid.h + (FT_CID_GetIsInternallyCIDKeyedFunc, + FT_CID_GetCIDFromGlyphIndexFunc): New function typedefs. + (CID Service): Use them. + + * src/base/ftcid.c: Include FT_CID_H. + (FT_Get_CID_Is_Internally_CID_keyed, FT_Get_CID_From_Glyph_Index): + New functions. + + * src/cff/cffdrivr.c (cff_get_is_cid, cff_get_cid_from_glyph_index): + New functions. + (cff_service_cid_info): Add them. + * src/cff/cffload.c (cff_font_load): Don't free `font->charset.sids' + -- it is needed for access as a CID-keyed font. It gets deleted + later on. + + * src/cid/cidriver.c (cid_get_is_cid, cid_get_cid_from_glyph_index): + New functions. + (cid_service_cid_info): Add them. + + * docs/CHANGES: Updated. + +2009-03-11 Bram Tassyns + + Fix Savannah bug #25597. + + * src/cff/cffparse.c (cff_parse_real): Don't allow fraction_length + to become larger than 9. + +2009-03-11 Werner Lemberg + + Fix Savannah bug #25814. + + * builds/unix/freetype2.in: As suggested in the bug report, move + @LIBZ@ to `Libs.private'. + +2009-03-11 Werner Lemberg + + Fix Savannah bug #25781. + We now simply check for a valid `offset', no longer handling `delta + = 1' specially. + + * src/sfnt/ttcmap.c (tt_cmap4_validate): Don't check `delta' for + last segment. + (tt_cmap4_set_range, tt_cmap4_char_map_linear, + tt_cmap4_char_map_binary): Check offset. + +2009-03-11 Werner Lemberg + + * src/base/Jamfile: Fix handling of ftadvanc.c. + Reported by Oran Agra . + +2009-03-10 Vincent Richomme + + Restructure Win32 and Wince compiler support. + + * src/builds/win32: Remove files for WinCE. + Move VC 2005 support to a separate directory. + Add directory for VC 2008 support. + + * src/builds/wince: New directory hierarchy for WinCE compilers + (VC 2005 and VC 2008). + +2009-03-09 Werner Lemberg + + More preparations for 2.3.9 release. + + * docs/CHANGES: Updated. + + * Jamfile, README: s/2.3.8/2.3.9/, s/238/239/. + +2009-03-09 Werner Lemberg + + * src/sfnt/rules.mk (SFNT_DRV_H): Add ttsbit0.c. + +2009-03-09 Alexey Kryukov + + Fix handling of EBDT formats 8 and 9 (part 2). + + This patch fixes the following problems in ttsbit0.c: + + . Bitmaps for compound glyphs were never allocated. + + . `SBitDecoder' refused to load metrics if some other metrics have + already been loaded. This condition certainly makes no sense for + recursive calls, so I've just disabled it. Another possibility + would be resetting `decoder->metrics_loaded' to false before + loading each composite component. However, we must restore the + original metrics after finishing the recursion; otherwise we can + get a misaligned glyph. + + . `tt_sbit_decoder_load_bit_aligned' incorrectly handled `x_pos', + causing some glyph components to be shifted too far to the right + (especially noticeable for small sizes). + + Note that support for grayscale bitmaps (not necessarily compound) is + completely broken in ttsbit0.c. + + * src/sfnt/tt_sbit_decoder_load_metrics: Always load metrics. + (tt_sbit_decoder_load_bit_aligned): Handle `x_pos' correctly in case + of `h == height'. + (tt_sbit_decoder_load_compound): Reset metrics after loading + components. + Allocate bitmap. + +2009-03-09 Werner Lemberg + + * builds/unix/configure.raw (version_info): Set to 9:20:3. + +2009-03-03 David Turner + + Protect SFNT kerning table parser against malformed tables. + + This closes Savannah BUG #25750. + + * src/sfnt/ttkern.c (tt_face_load_kern, tt_face_get_kerning): Fix a + bug where a malformed table would be successfully loaded but later + crash the engine during parsing. + +2009-03-03 David Turner + + Update documentation and bump version number to 2.3.9. + + * include/freetype/freetype.h: Bump patch version to 9. + * docs/CHANGES: Document the ABI break in 2.3.8. + * docs/VERSION.DLL: Update version numbers table for 2.3.9. + +2009-03-03 David Turner + + Remove ABI-breaking field in public PS_InfoFontRec definition. + + Instead, we define a new internal PS_FontExtraRec structure to + hold the additional field, then place it in various internal + positions of the corresponding FT_Face derived objects. + + * include/freetype/t1tables.h (PS_FontInfoRec): Remove the + `fs_type' field from the public structure. + * include/freetype/internal/psaux.h (T1_FieldLocation): New + enumeration `T1_FIELD_LOCATION_FONT_EXTRA'. + * include/freetype/internal/t1types.h (PS_FontExtraRec): New + structure. + (T1_FontRec, CID_FaceRec): Add it. + + * src/cid/cidload.c (cid_load_keyword): Handle + T1_FIELD_LOCATION_FONT_EXTRA. + * src/cid/cidtoken.h, src/type1/t1tokens.h, src/type42/t42parse.c: + Adjust FT_STRUCTURE and T1CODE properly to handle `FSType'. + * src/type1/t1load.c (t1_load_keyword): Handle + T1_FIELD_LOCATION_FONT_EXTRA. + + * include/freetype/internal/services/svpsinfo.h (PsInfo service): + Add `PS_GetFontExtraFunc' function typedef. + + * src/base/ftfstype.c: Include FT_INTERNAL_SERVICE_H and + FT_SERVICE_POSTSCRIPT_INFO_H. + (FT_Get_FSType_Flags): Use POSTSCRIPT_INFO service. + + * src/cff/cffdrivr.c (cff_service_ps_info): Updated. + * src/cid/cidriver.c (cid_ps_get_font_extra): New function. + (cid_service_ps_info): Updated. + * src/type1/t1driver.c (t1_ps_get_font_extra): New function. + (t1_service_ps_info): Updated. + * src/type42/t42drivr.c (t42_ps_get_font_extra): New function. + (t42_service_ps_info): Updated. + +2009-03-02 Alexey Kryukov + + Fix handling of EBDT formats 8 and 9. + + The main cycle in `blit_sbit' makes too many iterations: it actually + needs the count of lines in the source bitmap rather than in the + target image. + + * src/sfnt/ttsbit.c (blit_sbit) [FT_CONFIG_OPTION_OLD_INTERNALS]: + Add parameter `source_height' and use it for main loop. + (Load_SBit_Single) [FT_CONFIG_OPTION_OLD_INTERNALS]: Updated. + +2009-02-23 Werner Lemberg + + Fix Savannah bug #25669. + + * src/base/ftadvanc.h (FT_Get_Advances): Fix serious typo. + + * src/base/ftobjs.c (FT_Select_Metrics, FT_Request_Metrics): Fix + scaling factor for non-scalable fonts. + + * src/cff/cffdrivr.c (cff_get_advances): Use correct advance width + value to prevent incorrect scaling. + + * docs/CHANGES: Document it. + +2009-02-15 Matt Godbolt + + Fix Savannah bug #25588. + + * builds/unix/ftconfig.in (FT_MulFix_arm): Use correct syntax for + `orr' instruction. + +2009-02-11 Werner Lemberg + + * src/truetype/ttobjs.c (tt_check_trickyness): Add `DFKaiShu'. + Reported by David Bevan . + +2009-02-09 Werner Lemberg + + Fix Savannah bug #25495. + + * src/sfnt/sfobjs.c (sfnt_load_face): Test for bitmap strikes before + setting metrics and bbox values. This ensures that the check for a + font with neither a `glyf' table nor bitmap strikes can be performed + early enough to set metrics and bbox values too. + +2009-02-04 Werner Lemberg + + Fix Savannah bug #25480. + + * builds/unix/freetype-config.in: For --ftversion, don't use $prefix + but $includedir. + +2009-01-31 Werner Lemberg + + Minor docmaker improvements. + + * src/tools/docmaker/content.py (DocBlock::__init__): Ignore empty + code blocks. + +2009-01-25 Werner Lemberg + + Fix SCANCTRL handling in TTFs. + Problem reported by Alexey Kryukov . + + * src/truetype/ttinterp.c (Ins_SCANCTRL): Fix threshold handling. + +2009-01-23 Werner Lemberg + + Move FT_Get_FSType_Flags to a separate file. + Problem reported by Mickey Gabel . + + * src/base/ftobjs.c (FT_Get_FSType_Flags): Move to... + * src/base/ftfstype.c: This new file. + + * modules.cfg (BASE_EXTENSION): Add ftfstype.c. + + * docs/INSTALL.ANY: Updated. + + * builds/mac/*.txt, builds/amiga/*makefile*, + builds/win32/{visualc,visualce}/freetype.*, builds/symbian/*: + Updated. + +2009-01-22 suzuki toshiya + + * builds/unix/ftsystem.c (FT_Stream_Open): Fix 2 error + messages ending without "\n". + +2009-01-22 suzuki toshiya + + Fix Savannah bug #25347. + + * src/base/ftobjs.c (open_face_PS_from_sfnt_stream): Rewind + the stream to the original position passed to this function, + when ft_lookup_PS_in_sfnt_stream() failed. + (Mac_Read_sfnt_Resource): Rewind the stream to the head of + sfnt resource body, when open_face_PS_from_sfnt_stream() + failed. + +2009-01-19 Michael Lotz + + Fix Savannah bug #25355. + + * include/freetype/config/ftconfig.h (FT_MulFix_i386): Make + assembler code work with gcc 2.95.3 (as used by the Haiku project). + Add `cc' register to the clobber list. + +2009-01-18 Werner Lemberg + + Protect FT_Get_Next_Char. + + * src/sfnt/ttcmap.c (tt_cmap4_set_range): Apply fix similar to + change from 2008-07-22. + + Patch from Ronen Ghoshal . + +2009-01-18 Werner Lemberg + + Implement FT_Get_Name_Index for SFNT driver. + + * src/sfnt/sfdriver.c (sfnt_get_name_index): New function. + (sfnt_service_glyph_dict): Use it. + + Problem reported by Truc Truong . + +2009-01-18 Werner Lemberg + + * include/freetype/ftstroke.h (FT_Outline_GetInsideBorder): Fix + documentation. Problem reported by Truc Truong . + + * docs/CHANGES: Updated. + +2009-01-14 Werner Lemberg + + * Version 2.3.8 released. + ========================= + + + Tag sources with `VER-2-3-8'. + + * docs/VERSION.DLL: Update documentation and bump version number to + 2.3.8. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.7/2.3.8/, s/237/238/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 8. + + * builds/unix/configure.raw (version_info): Set to 9:19:3. + + * docs/release: Updated. + +2009-01-14 Werner Lemberg + + * builds/toplevel.mk (dist): Compress better. + +2009-01-13 Werner Lemberg + + * src/base/ftobjs.c (FT_Get_FSType_Flags): Cast for compilation + with C++. + +2009-01-13 Werner Lemberg + + Don't use stdlib.h and friends directly. + Reported by Mickey Gabel . + + * src/base/ftdbgmem.c: s//FT_CONFIG_STANDARD_LIBRARY_H/. + + * src/gzip/ftgzip.c, src/lzw/ftlzw.c, src/raster/ftmisc.h: + s//FT_CONFIG_STANDARD_LIBRARY_H/. + + * src/autofit/aftypes.h, src/autofit/afhints.c, + src/pshinter/pshalgo.c: s//FT_CONFIG_STANDARD_LIBRARY_H/ + + * src/lzw/ftlzw.c, src/base/ftdbgmem.c: Don't include stdio.h. + +2009-01-12 Werner Lemberg + + Avoid compiler warnings. + + * */*: s/do ; while ( 0 )/do { } while ( 0 )/. + Reported by Sean McBride . + +2009-01-12 Werner Lemberg + + Fix stdlib dependencies. + + Problem reported by Mickey Gabel . + + * include/freetype/config/ftstdlib.h (ft_exit): Removed. Unused. + + * src/autofit/afhints.c, src/base/ftlcdfil.c, src/smooth/ftsmooth.c: + s/memcpy/ft_memcpy/. + * src/psaux/t1decode.c: s/memset/ft_memset/, s/memcpy/ft_memcpy/. + +2009-01-11 Werner Lemberg + + * docs/formats.txt: Add link to PCF specification. + + * include/freetype/ftbdf.h (FT_Get_BDF_Property): Improve + documentation. + +2009-01-09 suzuki toshiya + + * src/base/ftadvanc.c (_ft_face_scale_advances, FT_Get_Advance, + FT_Get_Advances): Change the type of load_flags from FT_UInt32 to + FT_Int32, to match with the flags for FT_Load_Glyph(). + * src/cff/cffdrivr.c (cff_get_advances): Ditto. + * src/truetype/ttdriver.c (tt_get_advances): Ditto. + * include/freetype/ftadvanc.h (FT_Get_Advance, FT_Get_Advances): + Ditto. + * include/freetype/internal/ftdriver.h (FT_Face_GetAdvancesFunc): + Ditto. + +2009-01-09 Daniel Zimmermann + + * src/gxvalid/gxvmort.c (gxv_mort_feature_validate): Fix wrong + length check. From Savannah patch #6682. + +2009-01-09 Werner Lemberg + + Fix problem with T1_FIELD_{NUM,FIXED}_TABLE2. + + * src/psaux/psobjs.c (ps_parser_load_field_table): Don't handle + `count_offset' if it is zero (i.e., unused). Otherwise, the first + element of the structure which holds the data is erroneously + modified. Problem reported by Chi Nguyen . + +2009-01-09 suzuki toshiya + + * src/base/ftadvanc.c (_ft_face_scale_advances, FT_Get_Advance, + FT_Get_Advances): Extend the type of load_flags from FT_UInt to + FT_UInt32, to pass 32-bit flags on 16bit platforms. + * src/cff/cffdrivr.c (cff_get_advances): Ditto. + * src/truetype/ttdriver.c (tt_get_advances): Ditto. + * include/freetype/ftadvanc.h (FT_Get_Advance, FT_Get_Advances): + Ditto. + * include/freetype/internal/ftdriver.h (FT_Face_GetAdvancesFunc): + Ditto. + +2009-01-09 suzuki toshiya + + * src/base/ftobjs.c (FT_Done_Library): Issue an error message when + FT_Done_Face() cannot free all faces. If the list of the opened + faces includes broken face which FT_Done_Face() cannot free, + FT_Done_Library() retries FT_Done_Face() and it can fall into + an endless loop. See the discussion: + http://lists.gnu.org/archive/html/freetype-devel/2008-09/msg00047.html + http://lists.gnu.org/archive/html/freetype-devel/2008-10/msg00000.html + +2009-01-07 Werner Lemberg + + * docs/CHANGES: Document new key `a' in ftdiff. + +2009-01-06 Werner Lemberg + + * autogen.sh: Don't use GNUisms while calling sed. Problem reported + by Sean McBride. + +2009-01-06 Werner Lemberg + + * src/base/ftbitmap.c (FT_Bitmap_Convert): Handle FT_PIXEL_MODE_LCD + and FT_PIXEL_MODE_LCD_V. Problem reported by Chi Nguyen + . + +2009-01-06 Diego Pettenò + + * builds/unix/configure.raw: Don't call AC_CANONICAL_BUILD and + AC_CANONICAL_TARGET and use $host_os only. A nice explanation for + this change can be found at + http://blog.flameeyes.eu/s/canonical-target. + + From Savannah patch #6712. + +2009-01-06 Sean McBride + + * src/base/ftdbgmem.c (_debug_mem_dummy): Make it static. + + * src/base/ftmac.c: Remove some #undefs. + +2008-12-26 Werner Lemberg + + Set `face_index' field in FT_Face for all font formats. + + * cff/cffobjs.c (cff_face_init), winfonts/winfnt.c (FNT_Face_Init), + sfnt/sfobjs.c (sfnt_init_face): Do it. + + * docs/CHANGES: Document it. + +2008-12-22 Steve Grubb + + * builds/unix/ftsystem.c (FT_Stream_Open): Reject zero-length files. + Patch from Savannah bug #25151. + +2008-12-21 Werner Lemberg + + * src/pfr/pfrdrivr.c, src/winfonts/winfnt.c, src/cache/ftcmanag.c, + src/smooth/ftgrays.c, src/base/ftobjc.s, src/sfobjs.c: + s/_Err_Bad_Argument/_Err_Invalid_Argument/. The former is for + errors in the bytecode interpreter only. + +2008-12-21 Werner Lemberg + + * src/base/ftpfr.c (FT_Get_PFR_Metrics): Protect against NULL + arguments. + Fix return value for non-PFR fonts. Both problems reported by Chi + Nguyen . + +2008-12-21 anonymous + + FT_USE_MODULE declares things as: + + extern const FT_Module_Class + + (or similar for C++). However, the actual types of the variables + being declared are often different, e.g., FT_Driver_ClassRec or + FT_Renderer_Class. (Some are, indeed, FT_Module_Class.) + + This works with most C compilers (since those structs begin with an + FT_Module_Class struct), but technically it's undefined behavior. + + To quote the ISO/IEC 9899:TC2 final committee draft, section 6.2.7 + paragraph 2: + + All declarations that refer to the same object or function shall + have compatible type; otherwise, the behavior is undefined. + + (And they are not compatible types.) + + Most C compilers don't reject (or even detect!) code which has this + issue, but the GCC LTO development branch compiler does. (It + outputs the types of the objects while generating .o files, along + with a bunch of other information, then compares them when doing the + final link-time code generation pass.) + + Patch from Savannah bug #25133. + + * src/base/ftinit.c (FT_USE_MODULE): Include variable type. + + * builds/amiga/include/freetype/config/ftmodule.h, + include/freetype/config/ftmodule.h, */module.mk: Updated to declare + pass correct types to FT_USE_MODULE. + +2008-12-21 Hongbo Ni + + * src/autofit/aflatin.c (af_latin_hint_edges), + src/autofit/aflatin2.c (af_latin2_hint_edges), src/autofit/afcjk.c + (af_cjk_hint_edges): Protect against division by zero. This fixes + Savannah bug #25124. + +2008-12-18 Werner Lemberg + + * docs/CHANGES: Updated. + +2008-12-18 Bevan, David + + Provide API for accessing embedding and subsetting restriction + information. + + * include/freetype.h (FT_FSTYPE_INSTALLABLE_EMBEDDING, + FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING, + FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING, FT_FSTYPE_EDITABLE_EMBEDDING, + FT_FSTYPE_NO_SUBSETTING, FT_FSTYPE_BITMAP_EMBEDDING_ONLY): New + macros. + (FT_Get_FSType_Flags): New function declaration. + + * src/base/ftobjs.c (FT_Get_FSType_Flags): New function. + + * src/cid/cidtoken.h, src/type1/t1tokens.h, src/type42/t42parse.c + (t42_keywords): Handle `FSType'. + + * include/freetype/t1tables.h (PS_FontInfoRec): Add `fs_type' field. + +2008-12-17 Werner Lemberg + + * src/base/ftsynth.c (FT_GlyphSlot_Embolden): Don't use internal + macros so that copying the source code into an application works + out of the box. + +2008-12-17 Werner Lemberg + + * include/freetype/ftsynth.h, src/base/ftsynth.c: Move + FT_GlyphSlot_Own_Bitmap to... + * include/freetype/ftbitmap.h, src/base/ftbitmap.c: These files. + + * docs/CHANGES: Document it. + +2008-12-10 Werner Lemberg + + Generalize the concept of `tricky' fonts by introducing + FT_FACE_FLAG_TRICKY to indicate that the font format's hinting + engine is necessary for correct rendering. + + At the same time, slightly modify the behaviour of tricky fonts: + FT_LOAD_NO_HINTING is now ignored. To really force raw loading + of tricky fonts (without hinting), both FT_LOAD_NO_HINTING and + FT_LOAD_NO_AUTOHINT must be used. + + Finally, tricky TrueType fonts always use the bytecode interpreter + even if the patented code is used. + + * include/freetype/freetype.h (FT_FACE_FLAG_TRICKY, FT_IS_TRICKY): + New macros. + + * src/truetype/ttdriver.c (Load_Glyph): Handle new load flags + semantics as described above. + + * src/truetype/ttobjs.c (tt_check_trickyness): New function, using + code of ... + (tt_face_init): This function, now simplified and updated to new + semantics. + + * src/base/ftobjs.c (FT_Load_Glyph): Don't use autohinter for tricky + fonts. + + * docs/CHANGES: Document it. + +2008-12-09 Werner Lemberg + + Really fix Savannah bug #25010: An SFNT font with neither outlines + nor bitmaps can be considered as containing space `glyphs' only. + + * src/truetype/ttpload.c (tt_face_load_loca): Handle the case where + a `glyf' table is missing. + + * src/truetype/ttgload.c (load_truetype_glyph): Abort if we have no + `glyf' table but a non-zero `loca' entry. + (tt_loader_init): Handle missing `glyf' table. + + * src/base/ftobjs.c (FT_Load_Glyph): Undo change 2008-12-05. + + * src/sfnt/sfobjs.c (sfnt_load_face): A font with neither outlines + nor bitmaps is scalable. + +2008-12-05 Werner Lemberg + + * src/autofit/aflatin.c (af_latin_uniranges): Add more ranges. This + fixes Savannah bug #21190 which also provides a basic patch. + +2008-12-05 Werner Lemberg + + * include/freetype/freetype.h (FT_LOAD_ADVANCE_ONLY): Use value + 0x100 instead of 0x10000; the latter value is already occupied by + FT_LOAD_TARGET_LIGHT. Bug reported by James Cloos. + + + Handle SFNT with neither outlines nor bitmaps. This fixes Savannah + bug #25010. + + * src/base/ftobjs.c (FT_Load_Glyph): Reject fonts with neither + outlines nor bitmaps. + + * src/sfnt/sfobjs.c (sfnt_load_face): Don't return an error if there + is no table with glyphs. + + + * src/sfnt/ttload.c (tt_face_lookup_table): Improve debugging + message. + +2008-12-01 Werner Lemberg + + GDEF tables need `glyph_count' too for validation. Problem reported + by Chi Nguyen . + + * src/otvalid/otvgdef.c (otv_GDEF_validate), src/otvalid/otvalid.h + (otv_GDEF_validate), src/otvalid/otvmod.c (otv_validate): Pass + `glyph_count'. + +2008-11-29 Werner Lemberg + + * src/autofit/afcjk.c, src/base/ftoutln.c, src/base/ftrfork.c, + src/bdf/bdfdrivr.c, src/gxvalid/gxvmorx.c, src/otvalid/otvmath.c, + src/pcf/pcfdrivr.c, src/psnames/pstables.h, src/smooth/ftgrays.c, + src/tools/glnames.py, src/truetype/ttinterp.c, src/type1/t1load.c, + src/type42/t42objs.c, src/winfonts/winfnt.c: Fix compiler warnings + (Atari PureC). + +2008-11-29 James Cloos + + * src/type/t1load.c (mm_axis_unmap): Revert previous patch and fix + it correctly by using FT_INT_TO_FIXED (FreeType expects 16.16 values + in the /BlendDesignMap space). + +2008-11-29 James Cloos + + * src/type1/t1load.c (mm_axis_unmap): `blend_points' is FT_Fixed*, + whereas `design_points' is FT_Long*. Therefore, return blend rather + than design points. + +2008-11-27 Werner Lemberg + + * src/cff/cffparse.c (cff_parse_real): Handle more than nine + significant digits correctly. This fixes Savannah bug #24953. + +2008-11-25 Daniel Zimmermann + + * src/base/ftstream.c (FT_Stream_ReadFields): Don't access stream + before the NULL check. From Savannah patch #6681. + +2008-11-24 Werner Lemberg + + Fixes from the gnuwin32 port. + + * src/base/ftlcdfil.c: s/EXPORT/EXPORT_DEF/. + + * src/base/ftotval.c: Include FT_OPENTYPE_VALIDATE_H. + + * src/psaux/psobjs.c (ps_table_add): Check `length'. + +2008-11-15 Werner Lemberg + + * src/truetype/ttinterp.c (tt_default_graphics_state): The default + value for `scan_type' is zero, as confirmed by Greg Hitchcock from + Microsoft. Problem reported by Michal Nowakowski + . + +2008-11-12 Tor Andersson + + * src/cff/cffdrivr.c (cff_get_cmap_info): Initialize `format' field. + This fixes Savannah bug #24819. + +2008-11-08 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_load_face): Remove #if 0/#endif guards + since OpenType version 1.5 has been released. + + * include/ttnameid.h (TT_NAME_ID_WWS_FAMILY, + TT_NAME_ID_WWS_SUBFAMILY): New macros for OpenType 1.5. + (TT_URC_COPTIC, TT_URC_VAI, TT_URC_NKO, TT_URC_BALINESE, + TT_URC_PHAGSPA, TT_URC_NON_PLANE_0, TT_URC_PHOENICIAN, + TT_URC_TAI_LE, TT_URC_NEW_TAI_LUE, TT_URC_BUGINESE, + TT_URC_GLAGOLITIC, TT_URC_YIJING, TT_URC_SYLOTI_NAGRI, + TT_URC_LINEAR_B, TT_URC_ANCIENT_GREEK_NUMBERS, TT_URC_UGARITIC, + TT_URC_OLD_PERSIAN, TT_URC_SHAVIAN, TT_URC_OSMANYA, + TT_URC_CYPRIOT_SYLLABARY, TT_URC_KHAROSHTHI, TT_URC_TAI_XUAN_JING, + TT_URC_CUNEIFORM, TT_URC_COUNTING_ROD_NUMERALS, TT_URC_SUNDANESE, + TT_URC_LEPCHA, TT_URC_OL_CHIKI, TT_URC_SAURASHTRA, TT_URC_KAYAH_LI, + TT_URC_REJANG, TT_URC_CHAM, TT_URC_ANCIENT_SYMBOLS, + TT_URC_PHAISTOS_DISC, TT_URC_OLD_ANATOLIAN, TT_URC_GAME_TILES): New + macros for OpenType 1.5. + +2008-11-08 Wenlin Institute + + * src/base/ftobjs.c (ft_glyphslot_free_bitmap): Protect against + slot->internal == NULL. Reported by Graham Asher. + +2008-11-08 Werner Lemberg + + * src/sfnt/sfobjs.c (tt_face_get_name): Modified to return an error + code so that memory allocation problems can be distinguished from + missing table entries. Reported by Graham Asher. + (GET_NAME): New macro. + (sfnt_load_face): Use it. + +2008-11-05 Werner Lemberg + + * devel/ftoption.h, include/freetype/config/ftoption.h + [TT_CONFIG_OPTION_BYTECODE_INTERPRETER]: Undefine + TT_CONFIG_OPTION_UNPATENTED_HINTING. This fixes the return value of + `FT_Get_TrueType_Engine_Type' (and makes it work as documented). + Reported in bug #441638 of bugzilla.novell.com. + + * docs/CHANGES: Document it. + +2008-11-03 Werner Lemberg + + * src/type1/t1load.c (parse_subrs): Use an endless loop. There are + fonts (like HELVI.PFB version 003.001, used on OS/2) which define + some `subrs' elements more than once. Problem reported by Peter + Weilbacher . + +2008-10-15 Graham Asher + + * src/sfnt/ttpost.c (tt_post_default_names): Add `const'. + +2008-10-15 David Turner + + * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Disambiguate for + meddlesome compilers' warning against `for ( ...; ...; ...) ;'. + +2008-10-14 Werner Lemberg + + * src/cff/cffobjs.c (cff_face_init): Remove compiler warning. + Suggested by Bram Tassyns in Savannah patch #6651. + +2008-10-12 Graham Asher + + * src/sfnt/sfobjs.c (sfnt_load_face): Fix computation of + `underline_position'. + +2008-10-12 Werner Lemberg + + * docs/CHANGES: Updated. + +2008-10-09 suzuki toshiya + + Fix Savannah bug #24468. + + According to include/freetype/internal/ftobjs.h, the appropriate + type to interchange single character codepoint is FT_UInt32. It + should be distinguished from FT_UInt which can be 16bit integer. + + * src/sfnt/ttcmap.c (tt_cmap4_char_map_linear): Change the type + of the second argument `pcharcode' from FT_UInt* to FT_UInt32*. + (tt_cmap4_char_map_binary): Ditto. + (tt_cmap14_get_nondef_chars): Change the type of return value + from FT_UInt* to FT_UInt32*. + +2008-10-08 John Tytgat + + Fix Savannah bug #24485. + + * src/type1/t1load.c (parse_charstrings): Assure that we always have + a .notdef glyph. + +2008-10-05 suzuki toshiya + + * src/base/ftmac.c: Include FT_TRUETYPE_TAGS_H for multi build. + * builds/mac/ftmac.c: Ditto. + +2008-10-05 suzuki toshiya + + * include/freetype/tttags.h (TTAG_TYP1, TTAG_typ1): Fix definitions. + * src/base/ftobjs.c: Include FT_TRUETYPE_TAGS_H. + +2008-10-05 suzuki toshiya + + * src/sfnt/sfobjs.c (sfnt_open_font): Allow `typ1' version tag in + the beginning of sfnt container. + * src/sfnt/ttload.c (check_table_dir): Return + `SFNT_Err_Table_Missing' when sfnt table directory structure is + correct but essential tables for TrueType fonts (`head', `bhed' or + `SING') are missing. Other errors are returned by + SFNT_Err_Unknown_File_Format. + + * src/base/ftobjs.c (FT_Open_Face): When TrueType driver returns + `FT_Err_Table_Missing', try `open_face_PS_from_sfnt_stream'. It is + enabled only when old mac font support is configured. + +2008-10-04 suzuki toshiya + + * include/freetype/tttags.h (TTAG_CID, TTAG_FOND, TTAG_LWFN, + TTAG_POST, TTAG_sfnt, TTAG_TYP1, TTAG_typ1): New tags to simplify + the repeated calculations of these values in ftobjs.c and ftmac.c. + * src/base/ftobjs.c: Replace all FT_MAKE_TAG by new tags. + * src/base/ftmac.c: Ditto. + * builds/mac/ftmac.c: Ditto. + +2008-10-04 suzuki toshiya + + * src/base/ftobjs.c (ft_lookup_PS_in_sfnt_stream): Remove wrong + initialization of *is_sfnt_cid. + +2008-10-04 Werner Lemberg + + * src/base/ftobjs.c (open_face_PS_from_sfnt_stream): Remove compiler + warnings. + +2008-10-04 suzuki toshiya + + * src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Replaced by... + (ft_lookup_PS_in_sfnt_stream): This. + (open_face_PS_from_sfnt_stream): New function. It checks whether + the stream is sfnt-wrapped Type1 PS font or sfnt-wrapped CID-keyed + font, then try to open a face for given face_index. + (Mac_Read_sfnt_Resource): Replace the combination of + `ft_lookup_PS_in_sfnt' and `open_face_from_buffer' by + `open_face_PS_from_sfnt_stream'. + * src/base/ftmac.c (FT_New_Face_From_SFNT): Ditto. + * builds/mac/ftmac.c (FT_New_Face_From_SFNT): Ditto. + * src/base/ftbase.h: Remove `ft_lookup_PS_in_sfnt' and add + `open_face_PS_from_sfnt_stream'. + +2008-10-03 suzuki toshiya + + * src/base/ftobjs.c (ft_lookup_PS_in_sfnt): Set *is_sfnt_cid to + FALSE if neither `CID ' nor `TYP1' is found in the sfnt container. + +2008-10-03 suzuki toshiya + + * include/freetype/config/ftconfig.h: Define FT_MACINTOSH when SC or + MrC compiler of MPW is used. These compilers do not define the + macro __APPLE__ by themselves. + * builds/unix/ftconfig.in: Ditto. + * builds/vms/ftconfig.h: Ditto. + * src/base/ftbase.c: Use FT_MACINTOSH instead of __APPLE__, to + include ftmac.c if FreeType 2 is built by MPW. + * src/base/ftobjs.c: Use FT_MACINTOSH instead of __APPLE__, to + enable shared functions for ftmac.c if FreeType 2 is built by MPW. + + * builds/mac/ftmac.c: Include ftbase.h. + (memory_stream_close): Removed. + (new_memory_stream): Ditto. + (open_face_from_buffer): Removed. Use the implementation in + ftobjs.c. + (ft_lookup_PS_in_sfnt): Ditto. + + * builds/mac/FreeType.m68k_far.make.txt: Build ftmac.c as an + included part of ftbase.c, to share the functions in ftobjs.c. The + rule compiling ftmac.c separately is removed and the rule copying + ftbase.c from src/base/ftbase.c to builds/mac/ftbase.c is added. + * builds/mac/FreeType.m68k_cfm.make.txt: Ditto. + * builds/mac/FreeType.ppc_classic.make.txt: Ditto. + * builds/mac/FreeType.ppc_carbon.make.txt: Ditto. + +2008-10-02 Bram Tassyns + + * src/cff/cffgload.c (cff_slot_load): Map CID 0 to GID 0. This + fixes Savannah bug #24430. + +2008-10-02 Werner Lemberg + + * builds/freetype.mk (BASE_H): Rename to... + (INTERNAL_H): This. + (FREETYPE_H): Updated. + * src/base/rules.mk: (BASE_OBJ_S, OBJ_DIR/%.$O): Add BASE_H. + * src/bdf/rules.mk (BDF_DRV_H): Add bdferror.h. + * src/cache/rules.mk (CACHE_DRV_H): Add ftccache.h and ftcsbits.h. + * src/pcf/rules.mk (PCF_DRV_H): Add pcfread.h. + * src/raster/rules.mk (RASTER_DRV_H): Add ftmisc.h. + * src/type42/rules.mk (T42_DRV_H): Add t42types.h. + +2008-10-02 suzuki toshiya + + * src/base/ftbase.h: New file to declare the private utility + functions shared by the sources of base modules. Currently, + `ft_lookup_PS_in_sfnt' and `open_face_from_buffer' are declared to + share between ftobjs.c and ftmac.c. + + * src/base/rule.mk: Add ftbase.h. + + * src/base/ftobjs.c: Include ftbase.h. + (memory_stream_close): Build on any platform when old MacOS font + support is enabled. + (new_memory_stream): Ditto. + (open_face_from_buffer): Build on any platform when old MacOS font + support is enabled. The counting of the face in a font file is + slightly different between Carbon-dependent parser and Carbon-free + parser. They are merged with the platform-specific conditional. + (ft_lookup_PS_in_sfnt): Ditto. + + * src/base/ftmac.c: Include ftbase.h. + (memory_stream_close): Removed. + (new_memory_stream): Ditto. + (open_face_from_buffer): Removed. Use the implementation in + ftobjs.c. + (ft_lookup_PS_in_sfnt): Ditto. + +2008-10-02 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_load_face): `psnames_error' is only needed + if TT_CONFIG_OPTION_POSTSCRIPT_NAMES is defined. + +2008-10-01 Werner Lemberg + + * src/truetype/ttobjs.c (tt_face_done), src/cff/cffobjs.c + (cff_face_done), src/pfr/pfrobjs.c (pfr_face_done), + src/pcf/pcfdrivr.c (PCF_Face_Done), src/cid/cidobjs.c + (cid_face_done), src/bdf/bdfdrivr. (BDF_Face_Done), + src/sfnt/sfobjs.c (sfnt_face_done): Protect against face == 0. + Reported by Graham Asher. + +2008-09-30 suzuki toshiya + + * src/base/rules.mk: Add conditional source to BASE_SRC, for `make + multi' on Mac OS X. If the macro $(ftmac_c) is defined, + $(BASE_DIR)/$(ftmac_c) is added to BASE_SRC. In a normal build, the + lack of ftmac.c in BASE_SRC is not serious because ftbase.c includes + ftmac.c. + * builds/unix/unix-def.in: Add a macro definition of $(ftmac_c). + * builds/unix/configure.raw: Add procedure to set up appropriate + value of $(ftmac_c) with the consideration of the availability of + Carbon framework. + +2008-09-30 suzuki toshiya + + * src/base/Jamfile: Add target for multi build by jam on Mac OS X. + * src/base/ftobjs.c (FT_New_Face): Fix the condition to include this + function for MPW building. It is synchronized the condition to + include ftmac.c source into ftbase.c. + +2008-09-22 Werner Lemberg + + * src/cff/cffgload.c (CFF_Operator, cff_argument_counts, + cff_decoder_parse_charstrings): Handle (invalid) + `callothersubr' and `pop' instructions. + +2008-09-22 John Tytgat + + Fix Savannah bug #24307. + + * include/freetype/internal/t1types.h (CID_FaceRec), + src/type42/t42types.h (T42_FaceRec): Comment out `afm_data'. + +2008-09-21 Werner Lemberg + + * src/smooth/ftgrays.c (gray_raster_render): Don't dereference + `target_map' if FT_RASTER_FLAG_DIRECT is set. Problem reported by + Stephan T. Lavavej . + +2008-09-21 suzuki toshiya + + * src/otvalid/Jamfile: Add missing target `otvmath' for multi build + by jam. + * src/sfnt/Jamfile: Add missing target `ttmtx' for multi build by + jam. + +2008-09-20 Werner Lemberg + + * src/smooth/ftgrays.c (gray_find_cell): Fix threshold. The values + passed to this function are already `normalized'. Problem reported + by Stephan T. Lavavej . + + * docs/CHANGES: Document it. + +2008-09-20 Werner Lemberg + + * src/base/ftoutln.c: Include FT_INTERNAL_DEBUG_H. + (FT_Outline_Decompose): Decorate with tracing messages. + + * src/smooth/ftgrays.c [DEBUG_GRAYS]: Replace with + FT_DEBUG_LEVEL_TRACE. + [_STANDALONE_ && FT_DEBUG_LEVEL_TRACE]: Include stdio.h and + stdarg.h. + + (FT_TRACE) [_STANDALONE_]: Remove. + (FT_Message) [_STANDALONE_ && FT_DEBUG_LEVEL_TRACE]: New function. + (FT_TRACE5, FT_TRACE7) [_STANDALONE_]: New macros. + (FT_ERROR) [_STANDALONE_]: Updated. + + (gray_hline) [FT_DEBUG_LEVEL_TRACE]: Fix condition. + Use FT_TRACE7. + (gray_dump_cells): Make it `static void'. + (gray_convert_glyph): Use FT_TRACE7. + + (FT_Outline_Decompose) [_STANDALONE_]: Synchronize with version in + ftoutln.c. + + * src/base/ftadvanc.c (FT_Get_Advance, FT_Get_Advances): Use + FT_ERROR_BASE. + + * docs/formats.txt: Updated. + +2008-09-19 suzuki toshiya + + * src/base/ftmac.c: Import sfnt-wrapped Type1 and sfnt-wrapped + CID-keyed font support. + * builds/mac/ftmac.c: Ditto. + +2008-09-19 suzuki toshiya + + * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Fix double free bug in + sfnt-wrapped Type1 and sfnt-wrapped CID-keyed font support code. + `open_face_from_buffer' frees the passed buffer if it cannot open a + face from the buffer, so the caller must not free it. + +2008-09-19 suzuki toshiya + + * src/base/ftobjs.c (Mac_Read_sfnt_Resource): Add initial support + for sfnt-wrapped Type1 and sfnt-wrapped CID-keyed font. + (ft_lookup_PS_in_sfnt): New function to look up `TYP1' or `CID ' + table in sfnt table directory. It is used before loading TrueType + font driver. + + * docs/CHANGES: Add note about the current status of sfnt-wrapped + Type1 and sfnt-wrapped CID-keyed font support. + +2008-09-18 Werner Lemberg + + * src/base/ftsystem.c (FT_Done_Memory): Use ft_sfree directly for + orthogonality (ft_free and ft_sfree could belong to different memory + pools). This fixes Savannah bug #24297. + +2008-09-18 suzuki toshiya + + * src/cff/cffobjs.c (cff_face_init): Use TTAG_OTTO defined + in ttags.h instead of numerical value 0x4F54544FL. + +2008-09-16 Werner Lemberg + + * src/cff/cffgload.h, src/cff/cffgload.c + (cff_decoder_set_width_only): Eliminate function call. + +2008-09-15 George Williams + + Fix Savannah bug #24179, reported by Bram Tassyns. + + * src/type1/t1load.c (mm_axis_unmap, T1_Get_MM_Var): Fix computation + of default values. + +2008-09-15 Werner Lemberg + + * src/tools/glnames.py (main): Surround `ft_get_adobe_glyph_index' + and `ft_adobe_glyph_list' with FT_CONFIG_OPTION_ADOBE_GLYPH_LIST to + prevent unconditional definition. This fixes Savannah bug #24241. + + * src/psnames/pstables.h: Regenerated. + +2008-09-13 Werner Lemberg + + * autogen.sh, builds/unix/configure.raw, + include/freetype/config/ftconfig.h, builds/unix/ftconfig.in: Minor + beautifying. + + * include/freetype/ftadvanc.h, include/freetype/ftgasp.h, + include/freetype/ftlcdfil.h: Protect against FreeType 1. + Some other minor fixes. + + * devel/ftoption.h: Synchronize with + include/freetype/config/ftoption.h. + +2008-09-11 Werner Lemberg + + * src/base/ftbase.c: Include ftadvanc.c. + +2008-09-11 suzuki toshiya + + * builds/unix/ftconfig.in: Duplicate the cpp computation of + FT_SIZEOF_{INT|LONG} from include/freetype/config/ftconfig.h. + (FT_USE_AUTOCONF_SIZEOF_TYPES): New macro. If defined, the cpp + computation is disabled and the statically configured sizes are + used. This fixes Savannah bug #21250. + + * builds/unix/configure.raw: Add the checks to compare the cpp + computation results of the bit length of int and long versus the + sizes detected by running `configure'. If the results are + different, FT_USE_AUTOCONF_SIZEOF_TYPES is defined to prioritize the + results. + New option --{enable|disable}-biarch-config is added to define or + undefine FT_USE_AUTOCONF_SIZEOF_TYPES manually. + +2008-09-05 suzuki toshiya + + * builds/unix/configure.raw: Clear FT2_EXTRA_LIBS when Carbon or + ApplicationService framework is missing. Although this value is not + used in building of FreeType2, it is written in `freetype2.pc' and + `freetype-config'. + +2008-09-01 david turner + + * src/cache/ftccmap.c (FTC_CMapCache_Lookup): Accept a negative cmap + index to mean `use default cached FT_Face's charmap'. This fixes + Savannah bug #22625. + * include/freetype/ftcache.h: Document it. + + + Make FT_MulFix an inlined function. This is done to speed up + FreeType a little (on x86 3% when loading+hinting, 10% when + rendering, ARM savings are more important though). Disable this by + undefining FT_CONFIG_OPTION_INLINE_MULFIX. + + Use of assembler code can now be controlled with + FT_CONFIG_OPTION_NO_ASSEMBLER. + + * include/freetype/config/ftconfig.h, builds/unix/ftconfig.in + [!FT_CONFIG_OPTION_NO_ASSEMBLER] (FT_MulFix_arm): New assembler + implementation. + [!FT_CONFIG_OPTION_NO_ASSEMBLER] (FT_MulFix_i386): Assembler + implementation taken from `ftcalc.c'. + [!FT_CONFIG_OPTION_NO_ASSEMBLER] (FT_MULFIX_ASSEMBLER): New macro + which is defined to the platform-specific assembler implementation + of FT_MulFix. + [FT_CONFIG_OPTION_INLINE_MULFIX && FT_MULFIX_ASSEMBLER] + (FT_MULFIX_INLINED): New macro. + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_NO_ASSEMBLER, + FT_CONFIG_OPTION_INLINE_MULFIX): New macros. + + * include/freetype/freetype.h: Updated to handle FT_MULFIX_INLINED. + + * src/base/ftcalc.c: Updated to use FT_MULFIX_ASSEMBLER and + FT_MULFIX_INLINED. + + + Add a new header named FT_ADVANCES_H declaring some new APIs to + extract the advances of one or more glyphs without necessarily + loading their outlines. Also provide `fast loaders' for the + TrueType, Type1, and CFF font drivers (more to come later). + + * src/base/ftadvanc.c, include/freetype/ftadvanc.h: New files. + + * include/freetype/config/ftheader.h (FT_ADVANCES_H): New macro. + * include/freetype/freetype.h (FT_LOAD_ADVANCE_ONLY): New macro. + + * include/freetype/internal/ftdriver.h (FT_Face_GetAdvancesFunc): + `flags' and `advances' are now of type `FT_UInt' and `FT_Fixed', + respectively. + + * src/base/Jamfile (_sources), src/base/rules.mk (BASE_SRC): Add + ftadvanc.c. + + * src/cff/cffdrivr.c (cff_get_advances): New function. + (cff_driver_class): Register it. + + * src/cff/cffgload.c (cff_decoder_set_width_only): New function. + (cff_decoder_parse_charstrings): Handle `width_only'. + (cff_slot_load): Handle FT_LOAD_ADVANCE_ONLY. + + * src/cff/cffgload.h (cff_decoder): New element `width_only'. + (cff_decoder_set_width_only): New declaration. + + * src/truetype/ttdriver.c (tt_get_advances): New function. + (tt_driver_class): Register it. + + * src/truetype/ttgload.c (Get_HMetrics, Get_VMetrics): Renamed to... + (TT_Get_HMetrics, TT_Get_VMetrics): This. + Update callers. + * src/truetype/ttgload.h: Declare them. + + * src/type1/t1gload.h, src/type1/t1gload.c (T1_Get_Advances): New + function. + * src/type1/t1driver.c (t1_driver_class): Register T1_Get_Advances. + + + Add checks for minimum version of the `autotools' stuff. + + * autogen.sh: Implement it. + (get_major_version, get_minor_version, get_patch_version, + compare_to_minimum_version, check_tool_version): New auxiliary + functions. + + * README.CVS: Document it. + +2008-08-29 suzuki toshiya + + * src/sfnt/sfobjs.c (sfnt_open_font): Use TTAG_OTTO defined in + ttags.h instead of FT_MAKE_TAG( 'O', 'T', 'T', 'O' ). + +2008-08-28 Werner Lemberg + + * src/type1/t1load.c (parse_encoding): Protect against infinite + loop. This fixes Savannah bug #24150 (where a patch has been posted + too). + +2008-08-23 Werner Lemberg + + * src/type/t1afm.c (compare_kern_pairs), src/pxaux/afmparse.c + (afm_compare_kern_pairs): Fix comparison. This fixes Savannah bug + #24119. + +2008-08-19 suzuki toshiya + + * src/base/ftobjs.c (FT_Stream_New): Initialize *astream always, + even if passed library or arguments are invalid. This fixes a bug + that an uninitialized stream is freed when an invalid library handle + is passed. Originally proposed by Mike Fabian, 2008/08/18 on + freetype-devel. + (FT_Open_Face): Ditto (stream). + (load_face_in_embedded_rfork): Ditto (stream2). + +2008-08-18 suzuki toshiya + + * src/base/ftmac.c: Add a fallback to guess the availability of the + `ResourceIndex' type. It is used when built without configure + (e.g., a build with Jam). + * builds/mac/ftmac.c: Ditto. + * builds/unix/configure.raw: Set HAVE_TYPE_RESOURCE_INDEX to 1 or 0 + explicitly, even if `ResourceIndex' is unavailable. + +2008-08-18 suzuki toshiya + + * builds/unix/configure.raw: In checking of Mac OS X features, + all-in-one header file `Carbon.h' is replaced by the minimum + header file `CoreServices.h', similar to current src/base/ftmac.c. + +2008-08-18 suzuki toshiya + + * src/sfnt/ttcmap.c (tt_cmap2_validate): Skip the validation of + sub-header when its code_count is 0. Many Japanese Dynalab fonts + include such an empty sub-header (code_count == 0, first_code == 0 + delta == 0, but offset != 0) as the second sub-header in SJIS cmap. + +2008-08-04 Werner Lemberg + + * src/type1/t1tokens.h: Handle `ForceBold' keyword. This fixes + Savannah bug #23995. + + * src/cid/cidload.c (parse_expansion_factor): New callback function. + (cid_field_records): Use it for `ExpansionFactor'. + * src/cod/cidtoken.h: Handle `ForceBold' keyword. + Don't handle `ExpansionFactor'. + +2008-08-04 Bram Tassyns + + * src/cff/cffparse.c (cff_parse_fixed_scaled): Fix thinko which + resulted in incorrect scaling. This fixes Savannah bug #23973. + +2008-08-04 Werner Lemberg + + Be more tolerant w.r.t. invalid entries in SFNT table directory. + + * src/sfnt/ttload.c (check_table_dir): Ignore invalid entries and + adjust table count. + Add more trace messages. + (tt_face_load_font_dir): Updated. + +2008-07-30 Werner Lemberg + + * src/cff/cffgload.c (cff_decoder_parse_charstrings): No longer + assume that the first argument on the stack is the bottom-most + element. Two reasons: + + o According to people from Adobe it is missing in the Type 2 + specification that pushing of additional, superfluous arguments + on the stack is prohibited. + + o Acroread in general handles fonts differently, namely by popping + the number of arguments needed for a particular operand (as a PS + interpreter would do). In case of buggy fonts this causes a + different interpretation which of the elements on the stack are + superfluous and which not. + + Since there are CFF subfonts (embedded in PDFs) which rely on + Acroread's behaviour, FreeType now does the same. + +2008-07-27 Werner Lemberg + + Add extra mappings for `Tcommaaccent' and `tcommaaccent'. This + fixes Savannah bug #23940. + + * src/psnames/psmodule.c (WGL_EXTRA_LIST_SIZE): Rename to... + (EXTRA_GLYPH_LIST_SIZE): This. + Increase by 2. + (ft_wgl_extra_unicodes): Rename to... + (ft_extra_glyph_unicodes): This. + Add two code values. + (ft_wgl_extra_glyph_names): Rename to... + (ft_extra_glyph_names): This. + Add two glyphs. + (ft_wgl_extra_glyph_name_offsets): Rename to... + (ft_extra_glyph_name_offsets): This. + Add two offsets. + + (ps_check_wgl_name, ps_check_wgl_unicode): Rename to... + (ps_check_extra_glyph_name, ps_check_extra_glyph_unicode): This. + Updated. + (ps_unicodes_init): Updated. + +2008-07-26 Werner Lemberg + + * src/cff/cffgload.c (cff_decoder_prepare, + cff_decoder_parse_charstrings): Improve debug output. + +2008-07-22 Martin McBride + + * src/sfnt/ttcmap.c (tt_cmap4_validate, tt_cmap4_char_map_linear, + tt_cmap4_char_map_binary): Handle fonts which treat the last segment + specially. According to the specification, such fonts would be + invalid but acroread accepts them. + +2008-07-16 Jon Foster + + * src/pfr/pfrdrivr.c (pfr_get_advance): Fix off-by-one error. + + * src/base/ftcalc.c (FT_MulFix): Fix portability issue. + + * src/sfnt/ttpost.c (MAC_NAME) [!FT_CONFIG_OPTION_POSTSCRIPT_NAMES]: + Fix compiler warning. + +2008-07-16 Werner Lemberg + + Handle CID-keyed fonts wrapped in an SFNT (with cmaps) correctly. + + * src/cff/cffload.c (cff_font_load): Pass `pure_cff'. + Invert sids table only if `pure_cff' is set. + * src/cff/cffload.h: Udpated. + + * src/cff/cffobjs.c (cff_face_init): Updated. + Set FT_FACE_FLAG_CID_KEYED only if pure_cff is set. + + * docs/CHANGES: Updated. + +2008-07-09 Werner Lemberg + + * src/truetype/ttpload.c (tt_face_load_loca): Handle buggy fonts + where num_locations < num_glyphs. Problem reported by Ding Li. + +2008-07-05 Werner Lemberg + + Since FreeType uses `$(value ...)', we now need GNU make 3.80 or + newer. This fixes Savannah bug #23648. + + * configure: zsh doesn't like ${1+"$@"}. + Update needed GNU make version. + * builds/toplevel.mk: Check for `$(eval ...)'. + * docs/INSTALL.GNU, docs/INSTALL.CROSS, docs/INSTALL.UNIX: Document + it. + +2008-07-04 Werner Lemberg + + * src/raster/ftraster.c (Draw_Sweep): If span is smaller than one + pixel, only check for dropouts if neither start nor end point lies + on a pixel center. This fixes Savannah bug #23762. + +2008-06-29 Werner Lemberg + + * Version 2.3.7 released. + ========================= + + + Tag sources with `VER-2-3-7'. + + * docs/CHANGES, docs/VERSION.DLL: Update documentation and bump + version number to 2.3.7. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.6/2.3.7/, s/236/237/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 7. + + * builds/unix/configure.raw (version_info): Set to 9:18:3. + + * docs/release: Updated. + +2008-06-28 Werner Lemberg + + * src/ftglyph.c (FT_Matrix_Multiply, FT_Matrix_Invert): Move to... + * src/ftcalc.c: Here. This fixes Savannah bug #23729. + +2008-06-27 Werner Lemberg + + * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): Test for intersections which + degenerate to a single point can be ignored; this has been confirmed + by Greg Hitchcock from Microsoft. (This was commented out code.) + +2008-06-26 Werner Lemberg + + Improve navigation in API reference. + + * src/tools/docmaker/tohtml.py (html_header_3): Renamed to... + (html_header_6): This. + (html_header_3, html_header_3i, html_header_4, html_header_5, + html_header_5t): New strings. + (toc_footer_start, toc_footer_end): New strings. + (HtmlFormatter::html_header): Updated. + (HtmlFormatter::html_index_header, HtmlFormatter::html_toc_header): + New strings. + (HtmlFormatter::index_enter): Use `html_index_header'. + (HtmlFormatter::index_exit): Print `html_footer'. + (HtmlFormatter::toc_enter): Use `html_toc_header'. + (HtmlFormatter::toc_exit): Print proper footer. + + Convert ~ to non-breakable space. + + * src/tools/docmaker/tohtml.py (make_html_para): Implement it. + Update header files accordingly. + +2008-06-24 suzuki toshiya + + * builds/unix/configure.raw: Check type `ResourceIndex' explicitly + and define HAVE_TYPE_RESOURCE_INDEX if it is defined. Mac OS X 10.5 + bundles 10.4u SDK with MAC_OS_X_VERSION_10_5 macro but without + ResourceIndex type definition. The macro does not inform the type + availability. + * src/base/ftmac.c: More parentheses are inserted to clarify the + conditionals to disable legacy APIs in `10.5 and later' cases. If + HAVE_TYPE_RESOURCE_INDEX is not defined, ResourceIndex is defined. + +2008-06-24 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_SCANTYPE): Don't check rendering + mode. + + * src/raster/ftraster.c (Render_Glyph, Render_Gray_Glyph, + Draw_Sweep): No-dropout mode is value 2, not value 0. + (Draw_Sweep): Really skip dropout handling for no-dropout mode. + +2008-06-24 Werner Lemberg + + * src/psaux/psobjs.c (t1_builder_close_contour): Don't add contour + if it consists of one point only. Based on a patch from Savannah + bug #23683 (from John Tytgat). + +2008-06-22 Werner Lemberg + + * src/truetype/ttgload.c (TT_Load_Glyph): Protect bytecode stuff + with IS_HINTED. + + * docs/CHANGES: Updated. + +2008-06-22 suzuki toshiya + + * builds/unix/configure.raw: If CFLAGS has `-isysroot XXX' option + but LDFLAGS does not, import it to LDFLAGS. The option is used to + specify non-default SDK on Mac OS X (e.g., universal binary SDK for + Mac OS X 10.4 on PowerPC platform). Although Apple TechNote 2137 + recommends to add the option only to CFLAGS, LDFLAGS should include + it because libfreetype.la is built with -no-undefined. This fixes a + bug reported by Ryan Schmidt in MacPorts, + http://trac.macports.org/ticket/15331. + +2008-06-21 Werner Lemberg + + Enable access to the various dropout rules of the B&W rasterizer. + Pass dropout rules from the TT bytecode interpreter to the + rasterizer. + + * include/freetype/ftimage.h (FT_OUTLINE_SMART_DROPOUTS, + FT_OUTLINE_EXCLUDE_STUBS): New flags for for FT_Outline. + + * src/raster/ftraster.c (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, + Horizontal_Gray_Sweep_Drop): Use same mode numbers as given in the + OpenType specification. + Fix mode 4 computation. + (Render_Glyph, Render_Gray_Glyph): Handle new outline flags. + + * src/truetype/ttgload.c (TT_Load_Glyph) Convert scan conversion + mode to FT_OUTLINE_XXX flags. + + * src/truetype/ttinterp.c (Ins_SCANCTRL): Enable ppem check. + +2008-06-19 Werner Lemberg + + * src/cff/cffobjs.c (cff_face_init): Compute final + `dict->units_per_em' value before assigning it to + `cffface->units_per_EM'. Otherwise, CFFs without subfonts are + scaled incorrectly if the font matrix is non-standard. This fixes + Savannah bug #23630. + + * docs/CHANGES: Updated. + +2008-06-19 Werner Lemberg + + * src/type/t1objs.c (T1_Face_Init): Slightly improve algorithm fix + from 2008-06-19. + +2008-06-18 Werner Lemberg + + * src/type/t1objs.c (T1_Face_Init): Fix change from 2008-03-21. + Reported by Peter Weilbacher . + + * docs/CHANGES: Updated. + +2008-06-15 George Williams + + * src/otvalid/otvgpos.c (otv_MarkBasePos_validate): Set + `valid->extra2' to 1. This is undocumented in the OpenType 1.5 + specification. + +2008-06-15 Werner Lemberg + + * src/base/ftcalc.c (FT_MulFix) : Protect registers correctly + from clobbering. Patch from Savannah bug report #23556. + + * docs/CHANGES: Document it. + +2008-06-10 Werner Lemberg + + * autogen.sh: Add option `--install' to libtoolize. + +2008-06-10 Werner Lemberg + + * Version 2.3.6 released. + ========================= + + + Tag sources with `VER-2-3-6'. + + * docs/CHANGES, docs/VERSION.DLL: Update documentation and bump + version number to 2.3.6. + + * README, Jamfile (RefDoc), builds/win32/visualc/index.html, + builds/win32/visualc/freetype.dsp, + builds/win32/visualc/freetype.vcproj, + builds/win32/visualce/index.html, + builds/win32/visualce/freetype.dsp, + builds/win32/visualce/freetype.vcproj: s/2.3.5/2.3.6/, s/235/236/. + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 6. + + * builds/unix/configure.raw (version_info): Set to 9:17:3. + + + * include/freetype/internal/psaux.h (T1_BuilderRec): Remove `scale_x' + and `scale_y'. + * src/cff/cffgload.h (CFF_Builder): Remove `scale_x' and `scale_y'. + + + * src/cff/cffparse.c: Include FT_INTERNAL_DEBUG_H. + * src/cff/cffobjs.h: Include FT_INTERNAL_POSTSCRIPT_HINTS_H. + +2008-06-10 Werner Lemberg + + * src/base/ftobjs.c (open_face): Check `clazz->init_face' and + `clazz->done_face'. + +2008-06-09 VaDiM + + Support debugging on WinCE. From Savannah patch #6536; this fixes + bug #23497. + + * builds/win32/ftdebug.c (OutputDebugStringEx): New function/macro + as a replacement for OutputDebugStringA (which WinCE doesn't have). + Update all callers. + (ft_debug_init) [_WIN32_CE]: WinCE apparently doesn't have + environment variables. + +2008-06-09 Werner Lemberg + + * README.CVS: Updated. + + * builds/unix/configure.raw, builds/unix/freetype-config.in: Updated + for newer versions of autoconf and friends. + +2008-06-08 Werner Lemberg + + * src/type1/t1parse.h (T1_ParserRec): Make `base_len' and + `private_len' unsigned. + + * src/type1/t1parse.c (read_pfb_tag): Make `asize' unsigned and read + it as such. + (T1_New_Parser, T1_Get_Private_Dict): Make `size' unsigned. + + + * src/base/ftstream.c (FT_Stream_Skip): Reject negative values. + + + * src/type1/t1load.c (parse_blend_design_positions): Check `n_axis' + for sane value. + Fix typo. + + + * src/psaux/psobjs.c (ps_table_add): Check `idx' correctly. + + + * src/truetype/ttinterp (Ins_SHC): Use BOUNDS() to check + `last_point'. + + + * src/sfnt/ttload.c (tt_face_load_max_profile): Limit + `maxTwilightPoints'. + +2008-06-06 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_IP): Handle case `org_dist == 0' + correctly. This fixes glyphs `t' and `h' of Arial Narrow at 12ppem. + +2008-06-03 Werner Lemberg + + * include/freetype/ftcache.h (FTC_FaceID): Change type back to + FT_Pointer. Reported by Ian Britten . + +2008-06-02 Werner Lemberg + + Emit header info for defined FreeType objects in reference. + + * src/tools/docmaker/content.py (re_header_macro): New regexp. + (ContentProcessor::__init__): Initialize new dictionary `headers'. + (DocBlock::__init__): Collect macro header definitions. + + * src/tools/docmaker/tohtml.py (header_location_header, + header_location_footer): New strings. + (HtmlFormatter::__init__): Pass `headers' dictionary. + (HtmlFormatter::print_html_field): Don't emit paragraph tags. + (HtmlFormatter::print_html_field_list): Emit empty paragraph. + (HtmlFormatter::block_enter): Emit header info. + +2008-06-01 Werner Lemberg + + * include/freetype/config/ftheader.h (FT_UNPATENTED_HINTING_H, + FT_INCREMENTAL_H): Added. + +2008-05-28 Werner Lemberg + + * src/tools/docmaker/sources.py (SourceBlock::__init__): While + looking for markup tags, return immediately as soon a single one is + found. + +2008-05-28 Werner Lemberg + + * src/truetype/ttinterp.c (Ins_MD): The MD instruction also uses + original, unscaled input values. Confirmed by Greg Hitchcock from + Microsoft. + +2008-05-27 Werner Lemberg + + * src/tools/docmaker/tohtml.py (block_footer_start, + block_footer_middle): Beautify output. + +2008-05-25 Werner Lemberg + + * src/raster/ftraster.c (fc_black_render): Return 0 when we are + trying to render into a zero-width/height bitmap, not an error code. + + * src/truetype/ttgload.c (load_truetype_glyph): Move initialization + of the graphics state for subglyphs to... + (TT_Hint_Glyph): This function. + Hinting instructions for a composite glyph apparently refer to the + just hinted subglyphs, not the unhinted, unscaled outline. This + seems to fix Savannah bugs #20973 and (at least partially) #23310. + +2008-05-20 suzuki toshiya + + * src/base/ftmac.c (FT_New_Face_From_Suitcase): Check if valid + `aface' is returned by FT_New_Face_From_FOND(). The patch was + proposed by an anonymous reporter of Savannah bug #23204. + +2008-05-18 Werner Lemberg + + * src/pshinter/pshalgo.c (ps_hints_apply): Reset scale values after + correction for pixel boundary. Without this patch, the effect can + be cumulative under certain circumstances, making glyphs taller and + taller after each call. This fixes Savannah bug #19976. + +2008-05-18 Werner Lemberg + + * src/base/ftdebug.c (FT_Message, FT_Panic): Send output to stderr. + This fixes Savannah bug #23280. + + * docs/CHANGES: Updated. + +2008-05-18 David Turner + + * src/psnames/psmodule.c (ft_wgl_extra_unicodes, + ft_wgl_extra_glyph_names, ft_wgl_extra_glyph_name_offsets, + ps_check_wgl_name, ps_check_wgl_unicode): Use `static' to make + declarations non-global. + + * src/type1/t1load.c: Add missing comment. + +2008-05-17 Sam Hocevar + + * src/truetype/ttgload.c (TT_Load_Simple_Glyph): Handle zero-contour + glyphs correctly. Patch from Savannah bug #23277. + +2008-05-16 Werner Lemberg + + * docs/CHANGES: Updated. + +2008-05-16 Sergey Tolstov + + Improve support for WGL4 encoded fonts. + + * src/psnames/psmodule.c (WGL_EXTRA_LIST_SIZE): New macro. + (ft_wgl_extra_unicodes, ft_wgl_extra_glyph_names, + ft_wgl_extra_glyph_name_offsets): New arrays. + (ps_check_wgl_name, ps_check_wgl_unicode): New functions. + (ps_unicodes_init): Use them to add additional Unicode mappings. + +2008-05-15 Werner Lemberg + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) + : `closepath' without a path is a no-op, not an error + (cf. the PS reference manual). + + Reported by Martin McBride. + +2008-05-15 Werner Lemberg + + * builds/toplevel.mk (CONFIG_GUESS, CONFIG_SUB): Updated. + +2008-05-15 Werner Lemberg + + * src/type1/t1load.c (parse_subrs): Accept fonts with a subrs array + which contains a single but empty entry. This is technically + invalid (since it must end with `return'), but... + + Reported by Martin McBride. + +2008-05-14 Werner Lemberg + + Finish fix of scaling bug of CID-keyed CFF subfonts. + + * include/freetype/internal/ftcalc.h, src/base/ftcalc.c + (FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled): New + functions. + + * src/cff/cffobjs.h (CFF_Internal): New struct. It is used to + provide global hinting data for both the top-font and all subfonts + (with proper scaling). + + * src/cff/cffobjs.c (cff_make_private_dict): New function, using + code from `cff_size_init'. + (cff_size_init, cff_size_done, cff_size_select, cff_size_request): + Use CFF_Internal and handle subfonts. + (cff_face_init): Handle top-dict and subfont matrices correctly; + apply some heuristic in case of unlikely matrix concatenation + results. This has been discussed with people from Adobe (thanks + goes mainly to David Lemon) who confirm that the CFF specs are fuzzy + and not correct. + + * src/cff/cffgload.h (cff_decoder_prepare): Add `size' argument. + + * src/cff/cffgload.c (cff_builder_init): Updated. + (cff_decoder_prepare): Handle hints globals for subfonts. + Update all callers. + (cff_slot_load): Handling scaling of subfonts properly. + + * src/cff/cffparse.c (cff_parse_fixed_dynamic): New function. + (cff_parse_font_matrix): Use it. + + * src/cff/cfftypes.h (CFF_FontDictRec): Make `units_per_em' + FT_ULong. + + * docs/CHANGES: Document it. + +2008-05-13 Werner Lemberg + + * src/winfonts/winfnt.c (fnt_face_get_dll_font, FNT_Face_Init): + Handle case `face_index < 0'. + * docs/CHANGES: Document it. + +2008-05-04 Werner Lemberg + + First steps to fix the scaling bug of CID-keyed CFF subfonts, + reported by Ding Li on 2008/03/28 on freetype-devel. + + * src/base/cff/cffparse.c (power_tens): New array. + (cff_parse_real): Rewritten to introduce a fourth parameter which + returns the `scaling' of the real number so that we have no + precision loss. This is not used yet. + Update all callers. + (cff_parse_fixed_thousand): Replace with... + (cff_parse_fixed_scaled): This function. Update all callers. + +2008-05-03 Werner Lemberg + + * src/base/ftobjs.c (FT_Load_Glyph): Call the auto-hinter without + transformation since it recursively calls FT_Load_Glyph. This fixes + Savannah bug #23143. + +2008-04-26 Werner Lemberg + + * include/freetype/internal/psaux.h (T1_BuilderRec): Mark `scale_x' + and `scale_y' as obsolete since they aren't used. + * src/psaux/psobjs.c (t1_builder_init): Updated. + + * src/cff/cffgload.h (CFF_Builder): Mark `scale_x' and `scale_y' as + obsolete since they aren't used. + * src/cff/cffgload.c (cff_builder_init): Updated. + +2008-04-14 Werner Lemberg + + * src/pcf/pcfdrivr.c (PCF_Face_Init): Protect call to + `FT_Stream_OpenLZW' with `FT_CONFIG_OPTION_USE_LZ'. From Savannah + bug #22909. + +2008-04-13 Werner Lemberg + + * src/psaux/psconv.c (PS_Conv_ToFixed): Increase precision if + integer part is zero. + +2008-04-01 Werner Lemberg + + Fix compilation with g++ 4.1 (with both `single' and `multi' + targets). + + * src/base/ftobjs.c (FT_Open_Face): Don't define a variable in block + which is crossed by a `goto'. + + * src/otvalid/otvalid.h (otv_MATH_validate): Add prototype. + +2008-03-31 Werner Lemberg + + Fix support for subsetted CID-keyed CFFs. + + * include/freetype/freetype.h (FT_FACE_FLAG_CID_KEYED, + FT_IS_CID_KEYED): New macros. + + * src/cff/cffobjs.c (cff_face_init): Set number of glyphs to the + maximum CID value in CID-keyed CFFs. + Handle FT_FACE_FLAG_CID_KEYED flag. + + * docs/CHANGES: Document it. + + + Fix CFF font matrix calculation and improve precision. + + * src/cff/cffparse.c (cff_parse_real): Increase precision if integer + part is zero. + (cff_parse_font_matrix): Simplify computation of `units_per_em'; + this prevents overflow also. + + + Support FT_Get_CID_Registry_Ordering_Supplement for PS CID fonts. + + * src/cid/cidriver.c: Include FT_SERVICE_CID_H. + (cid_get_ros): New function. + (cid_service_cid_info): New service structure. + (cid_services): Register it. + +2008-03-23 Werner Lemberg + + Adjustments for Visual C++ 8.0, as reported by Rainer Deyke. + + * builds/compiler/visualc.mk (CFLAGS): Remove /W5. + (ANSIFLAGS): Add _CRT_SECURE_NO_DEPRECATE. + +2008-03-21 Laurence Darby + + * src/type1/t1objs.c (T1_Face_Init): Use `/Weight'. Patch from + Savannah bug #22675. + +2008-03-13 Derek Clegg + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Fix named style loop. + Patch from Savannah bug #22541. + +2008-03-03 Masatoshi Kimura + + * src/sfnt/ttcmap.c (tt_cmap14_char_map_nondef_binary, + tt_cmap14_find_variant): Return correct value. + (tt_cmap14_variant_chars): Fix check for `di'. + +2008-02-29 Wermer Lemberg + + * docs/CHANGES: Updated. + +2008-02-29 Wolf + + Add build support for symbian platform. From Savannah bug #22440. + + * builds/symbian/*: New files. + +2008-02-21 suzuki toshiya + + * src/base/ftmac.c (parse_fond): Fix a bug of PostScript font name + synthesis. For any face of a specified FOND, always the name for + the first face was used. Except of a FOND that refers multiple + Type1 font files, wrong synthesized font names are not used at all, + so this is an invisible bug. A few limit checks are added too. + + * builds/mac/ftmac.c: Ditto. + +2008-02-21 suzuki toshiya + + * builds/unix/configure.raw: Split compiler option to link Carbon + frameworks to one option for CoreServices framework and another + option for ApplicationServices framework. The split options can be + managed by GNU libtool to avoid unrequired duplication when FreeType + is linked with other applications. Suggested by Daniel Macks, + Savannah bug #22366. + +2008-02-18 Victor Stinner + + * src/truetype/ttinterp.c (Ins_IUP): Check number of points. Fix + from Savannah bug #22356. + +2008-02-17 Jonathan Blow + + * src/autofit/afloader.c (af_loader_load_g, af_loader_load_glyph): + Check for valid callback pointers. + +2008-02-15 suzuki toshiya + + * src/base/ftmac.c (FT_New_Face_From_SFNT): Check the sfnt resource + handle by its value instead of ResError(), fix provided by Deron + Kazmaier. According to the Resource Manager Reference, + GetResource(), Get1Resource(), GetNamedResource(), + Get1NamedResource() and RGetResource() set noErr but return NULL + handle when they can not find the requested resource. These + functions never return undefined values, so it is sufficient to + check if the handle is not NULL. + + * builds/mac/ftmac.c (FT_New_Face_From_SFNT): Ditto. + +2008-02-14 suzuki toshiya + + * src/base/ftbase.c: is replaced by "ftmac.c" as other + inclusion styles. Now it always includes src/base/ftmac.c; + builds/mac/ftmac.c is never included in any configuration. + + * builds/unix/configure.raw: Print warning if configure is executed + with options to specify Carbon functionalities explicitly. + + * docs/INSTALL.MAC: Note that legacy builds/mac/ftmac.c is not + included automatically and manual replacement is required. + +2008-02-11 Werner Lemberg + + * builds/modules.mk (CLOSE_MODULE, REMOVE_MODULE), builds/detect.mk + (dos_setup), builds/freetype.mk (clean_project_dos, + distclean_project_dos): Don't use \ but $(SEP). Reported by Duncan + Murdoch. + +2008-01-18 Sylvain Pasche + + * src/base/ftlcdfil.c (_ft_lcd_filter_legacy): Updated comment to + mention intra-pixel algorithm. + + * include/freetype/freetype.h (FT_Render_Mode): Mention that + FT_Library_SetLcdFilter can be used to reduce fringes. + +2008-01-16 Werner Lemberg + + * src/raster/ftraster.c (ft_black_render): Check `outline' before + using it. Reported by Allan Yang. + +2008-01-12 Werner Lemberg + + * src/raster/ftraster.c (FT_CONFIG_OPTION_5_GRAY_LEVELS): Remove. + +2008-01-12 Allan Yang, Jian Hua - SH + + * src/raster/ftraster.c (ft_black_init) + [FT_RASTER_OPTION_ANTI_ALIASING]: Fix compilation. + +2008-01-10 Werner Lemberg + + * src/truetype/ttgload.c (load_truetype_glyph): Handle the case + where the number of contours in a simple glyph is zero (and which + does contain an entry in the `glyf' table). This fixes Savannah bug + #21990. + +2008-01-04 suzuki toshiya + + Formatting suggested by Sean McBride. + + * builds/mac/ftmac.c: Formatting (tab expanded). + * src/autofit/afindic.c: Ditto. + * src/base/ftcid.c: Ditto. + * src/base/ftmac.c: Ditto. + +2007-12-30 Werner Lemberg + + * src/smooth/ftgrays.c (gray_raster_render): Check `outline' + correctly. + +2007-12-21 suzuki toshiya + + Improvement of POSIX resource-fork accessor to load unsorted + references in a resource. In HelveLTMM (resource-fork PostScript + Type1 font bundled with Mac OS X since 10.3.x), the appearance order + of PFB chunks is not sorted; sorting the chunks by reference IDs is + required. + + * include/freetype/internal/ftrfork.h (FT_RFork_Ref): New structure + type to store a pair of reference ID and offset to the chunk. + + * src/base/ftrfork.c (ft_raccess_sort_ref_by_id): New function to + sort FT_RFork_Ref by their reference IDs. + + (FT_Raccess_Get_DataOffsets): Returns an array of offsets that is + sorted by reference ID. + +2007-12-14 Werner Lemberg + + * src/cff/cffparse.c (cff_parse_real): Don't apply `power_ten' + division too early; otherwise the most significant digit(s) of the + final result are lost as the value is truncated to an integer. This + fixes Savannah bug #21794 (where the patch has been posted too). + +2007-12-06 Fix <4d876b82@gmail.com> + + Pass options from one configure script to another as-is (not + expanded). This is needed for options like + --includedir='${prefix}/include'. + + * builds/unix/detect.mk, configure: Prevent argument expansion in + call to the (real) `configure' script. + +2007-12-06 Werner Lemberg + + * src/truetype/ttgload.c (load_truetype_glyph): Fix compilation if + TT_USE_BYTECODE_INTERPRETER isn't defined. + +2007-12-06 Werner Lemberg + + There exist CFFs which contain opcodes for the Type 1 operators + `hsbw' and `closepath' which are both invalid in Type 2 charstrings. + However, it doesn't harm to support them. + + * src/cff/cffgload.c (CFF_Operator): Add `cff_op_hsbw' and + `cff_op_closepath.' + (cff_argument_counts): Ditto. + + (cff_decoder_parse_charstrings): Handle Type 1 opcodes 9 (closepath) + and 13 (hsbw) which are invalid in Type 2 charstrings. + +2007-12-06 suzuki toshiya + + * src/base/ftrfork.c (raccess_guess_darwin_newvfs): New function to + support new pathname syntax `..namedfork/rsrc' to access a resource + fork on Mac OS X. The legacy syntax `/rsrc' does not work on + case-sensitive HFS+. + (raccess_guess_darwin_hfsplus): Fix a bug in the calculation of + buffer size to store a pathname. + * include/freetype/internal/ftrfork.h: Increment the number of + resource fork guessing rule. + +2007-12-06 suzuki toshiya + + * builds/unix/configure.raw: Improve the compile tests to search + Carbon functions. + * builds/mac/ftmac.c: Import fixes for Carbon incompatibilities + proposed by Sean McBride from src/base/ftmac.c (see 2007-11-16). + +2007-12-06 suzuki toshiya + + The documents and comments for Mac OS X are improved by Sean + McBride. + + * src/base/ftmac.c: Fix a comment. + * include/freetype/ftmac.h: Ditto. + * docs/INSTALL.MAC: Improve English and add comment on lowest + system version specified by MACOSX_DEPLOYMENT_TARGET. + +2007-12-04 Werner Lemberg + + * src/cff/cffload.c (cff_subfont_load): Don't use logical OR to + concatenate error codes. + * src/sfnt/ttsbit.c (Load_SBit_Range): Ditto. + +2007-12-04 Graham Asher + + * src/truetype/ttobjs.c (tt_face_init): Don't use logical OR to + concatenate error codes. + +2007-12-04 Sean McBride + + * src/pfr/pfrgload.c (pfr_glyph_load_compound): Remove compiler + warning. + +2007-11-20 suzuki toshiya + + Fix MacOS legacy font support by Masatake Yamato on Mac OS X. It is + not working since 2.3.5. In FT_Open_New(), if FT_New_Stream() + cannot mmap() the specified file and cannot seek to head of the + specified file, it returns NULL stream and FT_Open_New() returns the + error immediately. On MacOS, most legacy MacOS fonts fall into such + a scenario because their data forks are zero-sized and cannot be + sought. To proceed to guessing of resource fork fonts, the + functions for legacy MacOS font must properly handle the NULL stream + returned by FT_New_Stream(). + + * src/base/ftobjs.c (IsMacBinary): Return error + FT_Err_Invalid_Stream_Operation immediately when NULL stream is + passed. + (FT_Open_Face): Even when FT_New_Stream() returns an error, proceed + to fallback. Originally, legacy MacOS font is tested in the cases + of FT_Err_Invalid_Stream_Operation (occurs when data fork is empty) + or FT_Err_Unknown_File_Format (occurs when AppleSingle header or + .dfont header is combined). Now the case of + FT_Err_Cannot_Open_Stream is included. + + * src/base/ftrfork.c (FT_Raccess_Guess): When passed stream is NULL, + skip FT_Stream_Seek(), which seeks to the head of stream, and + proceed to unit testing of raccess_guess_XXX(). FT_Stream_Seek() + for a NULL stream causes a Bus error on Mac OS X. + (raccess_guess_apple_double): Return FT_Err_Cannot_Open_Stream + immediately if passed stream is NULL. + (raccess_guess_apple_single): Ditto. + +2007-11-16 suzuki toshiya + + Fix for Carbon incompatibilities since Mac OS X 10.5, + proposed by Sean McBride. + + * doc/INSTALL.MAC: Comment on MACOSX_DEPLOYMENT_TARGET. + + * include/freetype/ftmac.h: Deprecate FT_New_Face_From_FOND and + FT_GetFilePath_From_Mac_ATS_Name. Since Mac OS X 10.5, calling + Carbon functions from a forked process is classified as unsafe + by Apple. All Carbon-dependent functions should be deprecated. + + * src/base/ftmac.c: Use essential header files + and + instead of + all-in-one header file . + + Include and replace HFS_MAXPATHLEN by Apple + genuine macro PATH_MAX. + + Add fallback macro for kATSOptionFlagsUnRestrictedScope which + is not found in Mac OS X 10.0. + + Multi-character constants ('POST', 'sfnt' etc) are replaced by + 64bit constants calculated by FT_MAKE_TAG() macro. + + For the index in the segment of resource fork, new portable + type ResourceIndex is introduced for better compatibility. + This type is since Mac OS X 10.5, so it is defined as short + when built on older platforms. + + (FT_ATSFontGetFileReference): If build target is only the systems + 10.5 and newer, it calls Apple genuine ATSFontGetFileReference(). + + (FT_GetFile_From_Mac_ATS_Name): Return an error if system is 10.5 + and newer or 64bit platform, because legacy type FSSpec type is + removed completely. + + (FT_New_Face_From_FSSpec): Ditto. + +2007-11-01 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_done_face): Check `sfnt' everywhere. This + fixes Savannah bug #21485. + +2007-10-29 Daniel Svoboda + + * src/winfonts/winfnt.c (FNT_Face_Init): Check first that the driver + can handle the font at all, then check `face_index'. Otherwise, the + driver might return the wrong error code. This fixes Savannah bug + #21468. + +2007-10-21 Werner Lemberg + + * src/sfnt/sfobjs.c (sfnt_load_face): Support bit 9 and prepare + support for bit 8 of the `fsSelection' field in the `OS/2' table. + MS is already using this; hopefully, this becomes part of OpenType + 1.5. + Prepare also support for `name' IDs 21 (WWS_FAMILY) and 22 + (WWS_SUBFAMILY). + +2007-10-20 Werner Lemberg + + * src/tools/docmaker/tohtml.py (html_header_2): Fix typo. + Add `td.left' element to CSS. + (toc_section_enter): Use it. + +2007-10-18 David Turner + + * include/freetype/freetype.h, src/base/ftobjs.c: Rename API + functions related to cmap type 14 support to the + `FT_Object_ActionName' scheme: + + FT_Get_Char_Variant_index -> FT_Face_GetCharVariantIndex + FT_Get_Char_Variant_IsDefault -> FT_Face_GetCharVariantIsDefault + FT_Get_Variant_Selectors -> FT_Face_GetVariantSelectors + FT_Get_Variants_Of_Char -> FT_Face_GetVariantsOfChar + FT_Get_Chars_Of_Variant -> FT_Face_GetCharsOfVariant + + Update documentation accordingly. + + * src/sfnt/ttcmap.c: Stronger cmap 14 validation. + Make the code a little more consistent with FreeType coding + conventions and modify the cmap14 functions that returned a newly + allocated array to use a persistent vector from the TT_CMap14 object + instead. + + (TT_CMap14Rec): Provide array and auxiliary data for result. + (tt_cmap14_done, tt_cmap14_ensure): New functions. + + (tt_cmap14_init, tt_cmap14_validate, tt_cmap14_char_map_def_binary, + tt_cmap14_char_map_nondef_binary, tt_cmap14_find_variant, + tt_cmap14_char_var_index, tt_cmap14_variants, + tt_cmap14_char_variants, tt_cmap14_def_char_count, + tt_cmap14_get_def_chars, tt_cmap14_get_nondef_chars, + tt_cmap14_variant_chars, tt_cmap14_class_rec): Updated and improved. + +2007-10-15 George Williams + + Add support for cmap type 14. + + * devel/ftoption.h, include/freetype/config/ftoption.h + (TT_CONFIG_CMAP_FORMAT_14): New macro. + + * include/freetype/internal/ftobjs.h (FT_CMap_CharVarIndexFunc, + FT_CMap_CharVarIsDefaultFunc, FT_CMap_VariantListFunc, + FT_CMap_CharVariantListFunc, FT_CMap_VariantCharListFunc): New + support function prototypes. + (FT_CMap_ClassRec): Add them. + Update all users. + + * include/freetype/ttnameid.h (TT_APPLE_ID_VARIANT_SELECTOR): New + macro. + + * include/freetype/freetype.h (FT_Get_Char_Variant_Index, + FT_Get_Char_Variant_IsDefault, FT_Get_Variant_Selectors, + FT_Get_Variants_Of_Char, FT_Get_Chars_Of_Variant): New API + functions. + + * src/base/ftobjs.c (find_variant_selector_charmap): New auxiliary + function. + (FT_Set_Charmap): Disallow cmaps of type 14. + (FT_Get_Char_Variant_Index, FT_Get_Char_Variant_IsDefault, + FT_Get_Variant_Selectors, FT_Get_Variants_Of_Char, + FT_Get_Chars_Of_Variant): New API functions. + + * src/sfnt/ttcmap.c (TT_PEEK_UINT24, TT_NEXT_UINT24): New macros. + + (TT_CMap14Rec, tt_cmap14_init, tt_cmap14_validate, + tt_cmap14_char_index, tt_cmap14_char_next, tt_cmap14_get_info, + tt_cmap14_char_map_def_binary, tt_cmap14_char_map_nondef_binary, + tt_cmap14_find_variant, tt_cmap14_char_var_index, + tt_cmap14_char_var_isdefault, tt_cmap14_variants, + tt_cmap14_char_variants, tt_cmap14_def_char_count, + tt_cmap14_get_def_chars, tt_cmap14_get_nondef_chars, + tt_cmap14_variant_chars, tt_cmap14_class_rec): New functions and + structures for cmap 14 support. + (tt_cmap_classes): Register tt_cmap14_class_rec. + (tt_face_build_cmaps): One more error message. + + * docs/CHANGES: Mention cmap 14 support. + +2007-10-01 Werner Lemberg + + * src/base/ftobjs.c (find_unicode_charmap): If search for a UCS-4 + charmap fails, do the loop again while searching a UCS-2 charmap. + This favours MS charmaps over Apple ones. + +2007-08-29 suzuki toshiya + + * src/base/ftmac.c: Introduction of abstract `short' data types, + ResFileRefNum and ResID. These types were introduced for Copland, + then backported to MPW. The variables exchanged with FileManager + QuickDraw frameworks are redefined by these data types. Patch was + proposed by Sean McBride. + * builds/mac/ftmac.c: Ditto. + +2007-08-18 Werner Lemberg + + * src/otvalid/otvcmmn.c (otv_x_y_ux_sy): Skip context glyphs. Found + by Imran Yousaf. Fixes Savannah bug #20773. + + (otv_Lookup_validate): Correct handling of LookupType. Found by + Imran Yousaf. Fixes Savannah bug #20782. + +2007-08-17 George Williams + + * src/otvalid/otvgsub.c (otv_SingleSubst_validate): Fix handling of + SingleSubstFormat1. + +2007-08-11 suzuki toshiya + + * builds/unix/configure.raw: Fix a bug which sets CC_BUILD by + ${build-gcc} (unchecked) instead of by ${build}-gcc (checked). + Found by Ryan Hill. + +2007-08-11 George Williams + + * src/otvalid/otvcommn.c, src/otvalid/otvcommn.h + (otv_Coverage_validate): Add fourth argument to pass an expected + count value. Update all users. + Check glyph IDs. + (otv_ClassDef_validate): Check `StartGlyph'. + + * src/otvalid/otvgsub.c (otv_SingleSubst_validate): More glyph ID + checks. + + * src/otvalid/otvmath.c (otv_MathConstants_validate): There are only + 56 constants. + (otv_GlyphAssembly_validate, otv_MathGlyphConstruction_validate): + Check glyph IDs. + +2007-08-08 Werner Lemberg + + * src/otvalid/otvbase.c, src/otvalid/otvcommn.c, + src/otvalid/otvgdef.c, src/otvalid/otvgpos.c, src/otvalid/otvgsub.c, + src/otvalid/otvjstf.c: s/FT_INVALID_DATA/FT_INVALID_FORMAT/ where + appropriate. Reported by George. + + * include/freetype/internal/fttrace.h: Define `trace_otvmath'. + + * src/otvalid/rules.mk (OTV_DRV_SRC): Add otvmath.c. + + * docs/CHANGES: Updated. + +2007-08-08 George Williams + + Add `MATH' validating support to otvalid module. + + * include/freetype/tttags.h (TTAG_MATH): New macro. + * include/freetype/ftotval.h (FT_VALIDATE_MATH): New macro. + (FT_VALIDATE_OT): Updated. + + * src/otvalid/otmath.c: New file. + + * src/otvalid/otvalid.c: Include otvmath.c. + * src/otvalid/otvmod.c (otv_validate): Handle `MATH' table. + +2007-08-04 Werner Lemberg + + * builds/unix/configure.raw: Add call to AC_LIBTOOL_WIN32_DLL. + Fixes Savannah bug #20686. + +2007-08-03 Werner Lemberg + + * src/psnames/psmodule.c: Fix usage of + FT_CONFIG_OPTION_POSTSCRIPT_NAMES macro. Reported by Graham Asher. + +2007-07-31 suzuki toshiya + + * src/base/ftmac.c (open_face_from_buffer): The argument + `driver_name' is typed as `const char*' to match with the + callers in FT_New_Face_From_LWFN and FT_New_Face_From_SFNT. + This is same with open_face_from_buffer in src/base/ftobjs.c. + Found and fixed by Sean McBride. + +2007-07-28 Werner Lemberg + + * src/raster/ftraster.c (count_table): Make it conditional. + * src/base/ftobjs.c (FT_New_Library): Check FT_RENDER_POOL_SIZE with + a preprocessor statement. + +2007-07-27 Werner Lemberg + + * src/base/ftoutln.c (FT_Outline_Translate): Check `outline' before + first usage. From Savannah patch #6115. + +2007-07-16 Werner Lemberg + + * docs/CHANGES: Updated. + +2007-07-16 Derek Clegg + + Add new service for getting the ROS from a CID font. + + * include/freetype/config/ftheader.h (FT_CID_H): New macro. + * include/freetype/ftcid.h: New file. + + * include/freetype/internal/ftserv.h (FT_SERVIVE_CID_H): New macro. + * include/freetype/internal/services/svcid.h: New file. + + * src/base/ftcid.c: New file. + + * src/cff/cffdrivr.c: Include FT_SERVICE_CID_H. + (cff_get_ros): New function. + (cff_service_cid_info): New service structure. + (cff_services): Register it. + + * src/cff/cffload.c (cff_font_done): Free registry and ordering. + + * src/cff/cfftypes.h (CFF_FontRec): Add `registry' and `ordering'. + + * modules.cfg (BASE_EXTENSIONS): Add ftcid.c. + +2007-07-11 Derek Clegg + + Add support for postscript name service to CFF driver. + + * src/cff/cffdrivr.c: Include FT_SERVICE_POSTSCRIPT_NAME_H. + (cff_get_ps_name): New function. + (cff_service_ps_name): New service structure. + (cff_services): Register it. + +2007-07-07 Werner Lemberg + + * src/base/ftglyph.c (FT_Glyph_Copy): Fix initialization of + `target'. Reported by Sean McBride. + +2007-07-06 Werner Lemberg + + * src/pfr/pfrcmap.c: Include pfrerror.h. + + * src/autofit/afindic.c: Add some external declarations to pacify + `make multi' compilation. + + * src/cid/cidgload.c (cid_load_glyph): Pacify compiler. + + * src/cff/cffdrivr.c (cff_ps_get_font_info), src/cff/cffobjs.c + (cff_strcpy), include/freetype/internal/ftmemory.h (FT_MEM_STRDUP), + src/autofit/aflatin.c (af_latin_hints_compute_edges), + src/autofit/afcjk.c (af_cjk_hints_compute_edges), src/sfnt/ttmtx.c + (tt_face_get_metrics), src/base/ftobjs.c (open_face) + [FT_CONFIG_OPTION_INCREMENTAL]: Fix compilation with C++ compiler. + + * docs/release: Mention test compilation targets. + +2007-07-04 Werner Lemberg + + * docs/PROBLEMS: Mention that some PS based fonts can't be + handled correctly by FreeType. + + * src/truetype/ttgload.c (load_truetype_glyph): Always allow a + recursion depth of 1. This was the maximum value in TrueType 1.0, + and some older fonts don't set this field correctly. + + * src/gxvalid/gxvmort1.c + (gxv_mort_subtable_type1_substTable_validate): Fix tracing message. + +2007-07-03 Werner Lemberg + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Initialize + `round' to pacify compiler. + 2007-07-02 Werner Lemberg @@ -564,7 +6059,7 @@ * src/base/ftglyph.c (FT_Glyph_Copy): Always set second argument to zero in case of error. This fixes Savannah bug #19689. -2007-04-25 Boris Letocha +2007-04-25 Boris Letocha * src/truetype/ttobjs.c: Fix a typo that created a speed regression in the TrueType bytecode loader. @@ -1363,7 +6858,7 @@ * src/base/ftmac.c: Specialized for Mac OS X only. * builds/unix/ftconfig.in: Fixed for ppc64 missing Carbon framework. - * builds/unix/configure.raw: Ditto. When explicit switches for + * builds/unix/configure.raw: Ditto. When explicit switches for FSSpec/FSRef/QuickDraw/ATS availability are given to configure, builds/mac/ftmac.c is used instead of default src/base/ftmac.c. @@ -1405,8 +6900,8 @@ 2006-12-08 Vladimir Volovich - * src/tools/apinames (State): Remove final comma in structure -- xlc - v5 under AIX 4.3 doesn't like this. + * src/tools/apinames.c (State): Remove final comma in structure -- + xlc v5 under AIX 4.3 doesn't like this. 2006-12-07 David Turner @@ -1922,22 +7417,22 @@ Fix miscellaneous compiler warnings. - * freetype2/include/freetype/internal/ftobjs.h: Close comment with - `*/' to avoid `/* in comment' compiler warning. + * include/freetype/internal/ftobjs.h: Close comment with `*/' to + avoid `/* in comment' compiler warning. - * freetype2/src/base/ftdbgmem.c (ft_mem_table_get_source): Turn cast + * src/base/ftdbgmem.c (ft_mem_table_get_source): Turn cast `(FT_UInt32)(void*)' into `(FT_UInt32)(FT_PtrDist)(void*)' since on 64-bit platforms void* is larger than FT_UInt32. - * freetype2/src/base/ftobjs.c (t_validator_error): Cast away + * src/base/ftobjs.c (t_validator_error): Cast away volatileness of argument to ft_longjmp. Spotted by Werner `Putzfrau' Lemberg. - * freetype2/src/bdf/bdflib.c (bdf_load_font): Initialize local + * src/bdf/bdflib.c (bdf_load_font): Initialize local variable `lineno'. - * freetype2/src/gxvalid/gxvmod.c (classic_kern_validate): Mark local - variable `error' as volatile. + * src/gxvalid/gxvmod.c (classic_kern_validate): Mark local variable + `error' as volatile. 2006-08-27 Werner Lemberg @@ -1950,30 +7445,29 @@ about addresses of volatile objects passed as function arguments as non-volatile pointers. - * freetype2/include/freetype/internal/ftvalid.h: Make FT_Validator - typedef a pointer to a volatile object. + * include/freetype/internal/ftvalid.h: Make FT_Validator typedef a + pointer to a volatile object. - * freetype2/src/gxvalid/gxvmod.c (gxv_load_table): Make function - argument `table' a pointer to a volatile object. + * src/gxvalid/gxvmod.c (gxv_load_table): Make function argument + `table' a pointer to a volatile object. - * freetype2/src/otvalid/otvmod.c (otv_load_table): Make function - argument `table' a pointer to a volatile object. + * src/otvalid/otvmod.c (otv_load_table): Make function argument + `table' a pointer to a volatile object. 2006-08-18 Jens Claudius - * freetype2/src/gxvalid/gxvmod.c (GXV_TABLE_DECL): Mark local - variable `_sfnt' as volatile since it must keep its value across - a call to ft_setjmp. + * src/gxvalid/gxvmod.c (GXV_TABLE_DECL): Mark local variable `_sfnt' + as volatile since it must keep its value across a call to ft_setjmp. (gxv_validate): Same for local variables `memory' and `valid'. (classic_kern_validate): Same for local variables `memory', `ckern', and `valid'. - * freetype2/src/otvalid/otvmod.c (otv_validate): Same for function - parameter `face' and local variables `base', `gdef', `gpos', `gsub', - `jstf', and 'valid'. + * src/otvalid/otvmod.c (otv_validate): Same for function parameter + `face' and local variables `base', `gdef', `gpos', `gsub', `jstf', + and 'valid'. - * freetype2/src/sfnt/ttcmap.c (tt_face_build_cmaps): Same for - local variable `cmap'. + * src/sfnt/ttcmap.c (tt_face_build_cmaps): Same for local variable + `cmap'. 2006-08-16 David Turner @@ -1984,7 +7478,7 @@ buggy by design. Always return -1. - Improvements to native TrueType hinting. This is a first try, + Improvements to native TrueType hinting. This is a first try, controlled by the FIX_BYTECODE macro in src/truetype/ttinterp.c. * include/freetype/internal/ftgloadr.h (FT_GlyphLoadRec): Add member @@ -2030,44 +7524,43 @@ `ft_validator_run' wrapping `setjmp' can cause a crash, as found by Jens: - http://lists.nongnu.org/archive/html/freetype-devel/2006-08/msg00004.htm. + http://lists.gnu.org/archive/html/freetype-devel/2006-08/msg00004.htm. - * freetype2/src/otvalid/otvmod.c: Replace `ft_validator_run' by - `ft_setjmp'. It reverts the change introduced on 2005-08-20. + * src/otvalid/otvmod.c: Replace `ft_validator_run' by `ft_setjmp'. + It reverts the change introduced on 2005-08-20. - * freetype2/src/gxvalid/gxvmod.c: Ditto. + * src/gxvalid/gxvmod.c: Ditto. 2006-08-13 Jens Claudius - * freetype2/include/freetype/internal/psaux.h: (T1_TokenType): Add + * finclude/freetype/internal/psaux.h: (T1_TokenType): Add T1_TOKEN_TYPE_KEY. (T1_FieldRec): Add `dict'. (T1_FIELD_DICT_FONTDICT, T1_FIELD_DICT_PRIVATE): New macros. (T1_NEW_XXX, T1_FIELD_XXX): Update to take the dictionary where a PS keyword is expected as an additional argument. - * freetype2/src/cid/cidload.c: (cid_field_records): Adjust - invocations of T1_FIELD_XXX. + * src/cid/cidload.c: (cid_field_records): Adjust invocations of + T1_FIELD_XXX. - * freetype2/src/cid/cidtoken.h: Adjust invocations of T1_FIELD_XXX. + * src/cid/cidtoken.h: Adjust invocations of T1_FIELD_XXX. - * freetype2/src/psaux/psobjs.c: Add macro FT_COMPONENT for tracing. + * src/psaux/psobjs.c: Add macro FT_COMPONENT for tracing. (ps_parser_to_token): Report a PostScript key as T1_TOKEN_TYPE_KEY, not T1_TOKEN_TYPE_ANY. (ps_parser_load_field): Make sure a token that should be a string or name is really a string or name. Avoid memory leak if a keyword has been already encountered and its value is overwritten. - * freetype2/src/type1/t1load.c: (t1_keywords): Adjust invocations of + * src/type1/t1load.c: (t1_keywords): Adjust invocations of T1_FIELD_XXX. (parse_dict): Ignore keywords that occur in the wrong dictionary (e.g., in `Private' instead of `FontDict'). - * freetype2/src/type1/t1tokens.h: Adjust invocations of - T1_FIELD_XXX. + * src/type1/t1tokens.h: Adjust invocations of T1_FIELD_XXX. - * freetype2/src/type42/t42parse.c: (t42_keywords): Adjust - invocations of T1_FIELD_XXX. + * src/type42/t42parse.c: (t42_keywords): Adjust invocations of + T1_FIELD_XXX. 2006-07-18 Jens Claudius @@ -2078,19 +7571,18 @@ Call the finisher for T1_Decoder in `cid_face_compute_max_advance' and `T1_Compute_Max_Advance'. - * freetype2/include/freetype/internal/psaux.h (T1_DecoderRec): - Remove field `face', add `len_buildchar'. + * include/freetype/internal/psaux.h (T1_DecoderRec): Remove field + `face', add `len_buildchar'. - * freetype2/include/freetype/internal/t1types.h (T1_FaceRec): Add - field `buildchar'. + * include/freetype/internal/t1types.h (T1_FaceRec): Add field + `buildchar'. - * freetype2/src/cid/cidgload.c (cid_face_compute_max_advance): Call - finisher for T1_Decoder. + * src/cid/cidgload.c (cid_face_compute_max_advance): Call finisher + for T1_Decoder. (cid_slot_load_glyph): Do not ignore failure when initializing the T1_Decoder. - * freetype2/src/psaux/t1decode.c (t1_decoder_parse_charstrings): - Updated. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Updated. (t1_decoder_init): Remove initialization of fields `buildchar' and `len_buildchar'. (t1_decoder_done): Remove deallocation of field `buildchar'. @@ -2102,46 +7594,45 @@ `len_buildchar'; make sure to call finisher for T1_Decoder even in case of error. - * freetype2/src/type1/t1load.c (T1_Open_Face): Allocate new field - `buildchar' of T1_FaceRec. + * src/type1/t1load.c (T1_Open_Face): Allocate new field `buildchar' + of T1_FaceRec. - * freetype2/src/type1/t1objs.c (T1_Face_Done): Free new field - `buildchar' of T1_FaceRec. + * src/type1/t1objs.c (T1_Face_Done): Free new field `buildchar' of + T1_FaceRec. 2006-07-14 Jens Claudius - * freetype2/include/freetype/internal/psaux.h: New macros - IS_PS_NEWLINE, IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, - IS_PS_XDIGIT, and IS_PS_BASE85 (from freetype2/src/psaux/psconv.h). + * include/freetype/internal/psaux.h: New macros IS_PS_NEWLINE, + IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT, + and IS_PS_BASE85 (from src/psaux/psconv.h). (T1_FieldLocation): Add T1_FIELD_LOCATION_LOADER, T1_FIELD_LOCATION_FACE, and T1_FIELD_LOCATION_BLEND. (T1_DecoderRec): New fields `buildchar' and `face'. (IS_PS_TOKEN): New macro. - * freetype2/include/freetype/internal/t1types.h (T1_FaceRec): New - fields `ndv_idx', `cdv_idx', and `len_buildchar'. + * include/freetype/internal/t1types.h (T1_FaceRec): New fields + `ndv_idx', `cdv_idx', and `len_buildchar'. - * freetype2/include/freetype/t1tables.h (PS_BlendRec): New fields + * include/freetype/t1tables.h (PS_BlendRec): New fields `default_design_vector' and `num_default_design_vector'. - * freetype2/src/psaux/psconv.h: Move macros IS_PS_NEWLINE, - IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT, - and IS_PS_BASE85 to freetype2/include/freetype/internal/psaux.h. + * src/psaux/psconv.h: Move macros IS_PS_NEWLINE, IS_PS_SPACE, + IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT, and + IS_PS_BASE85 to include/freetype/internal/psaux.h. - * freetype2/src/psaux/psobjs.c (ps_parser_to_token_array): Allow - `token' argument to be NULL if we want only to count the number of - tokens. + * src/psaux/psobjs.c (ps_parser_to_token_array): Allow `token' + argument to be NULL if we want only to count the number of tokens. (ps_tocoordarray): Allow `coords' argument to be NULL if we just want to skip the array. (ps_tofixedarray): Allow `values' argument to be NULL if we just want to skip the array. - * freetype2/src/psaux/t1decode.c (t1_decoder_parse_charstrings): Add - support for (partially commented out) othersubrs 19-25, 27, and 28. + * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Add support + for (partially commented out) othersubrs 19-25, 27, and 28. (t1_decoder_init): Initialize new fields `face' and `buildchar'. (t1_decoder_done): Release new field `buildchar'. - * freetype2/src/type1/t1load.c (parse_buildchar, parse_private): New + * src/type1/t1load.c (parse_buildchar, parse_private): New functions. (t1_keywords): Register them. (t1_allocate_blend): Updated. @@ -2156,12 +7647,12 @@ `len_buildchar'. Remove `keywords_flags'. - * freetype2/src/type1/t1load.h (T1_LoaderRect): New field + * src/type1/t1load.h (T1_LoaderRect): New field `keywords_encountered'. (T1_PRIVATE, T1_FONTDIR_AFTER_PRIVATE): New macros. - * freetype2/src/type1/t1tokens.h [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: - New entries for parsing /NDV, /CDV, and /DesignVector. + * src/type1/t1tokens.h [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: New + entries for parsing /NDV, /CDV, and /DesignVector. 2006-07-07 Werner Lemberg @@ -2230,7 +7721,7 @@ 2006-06-24 Eugeniy Meshcheryakov Fix two hinting bugs as reported in - http://lists.nongnu.org/archive/html/freetype-devel/2006-06/msg00057.html. + http://lists.gnu.org/archive/html/freetype-devel/2006-06/msg00057.html. * include/freetype/internal/tttypes.h (TT_GlyphZoneRec): Add `first_point' member. @@ -2441,7 +7932,7 @@ ---------------------------------------------------------------------------- -Copyright 2006, 2007 by +Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/lib/3rdparty/freetype/ChangeLog.21 b/lib/3rdparty/freetype/ChangeLog.21 index 3a1bcf0c11d..d6371d17583 100644 --- a/lib/3rdparty/freetype/ChangeLog.21 +++ b/lib/3rdparty/freetype/ChangeLog.21 @@ -922,7 +922,7 @@ (tt_driver_class): Updated. * src/truetype/ttgload.c (TT_Get_Metrics): Renamed to... - (tt_face_get_metrics): This. Provide version for FT_OPTIMIZE_MEMORY. + (tt_face_get_metrics): This. Provide version for FT_OPTIMIZE_MEMORY. Update all callers. (Get_Advance_Widths): Replaced with... (Get_Advance_WidthPtr): This. Provide version for @@ -1221,7 +1221,7 @@ 2004-11-16 Owen Taylor * builds/unix/freetype-config.in: Suppress -L$libdir for - /usr/lib64 as well as /usr/lib. (Reported by Dan Winship - + /usr/lib64 as well as /usr/lib. (Reported by Dan Winship - https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=139199) 2004-11-11 Werner Lemberg @@ -3554,7 +3554,7 @@ - the image and sbit cache are now abstract classes, that can be extended much more easily by client applications - - better performance in certain areas. Further optimizations + - better performance in certain areas. Further optimizations to come shortly anyway... - the FTC_CMapCache_Lookup function has changed its signature, @@ -9423,7 +9423,7 @@ ---------------------------------------------------------------------------- -Copyright 2002, 2003, 2004, 2005, 2007 by +Copyright 2002, 2003, 2004, 2005, 2007, 2008 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/lib/3rdparty/freetype/ChangeLog.22 b/lib/3rdparty/freetype/ChangeLog.22 index 22bf4f91895..4144288a5bf 100644 --- a/lib/3rdparty/freetype/ChangeLog.22 +++ b/lib/3rdparty/freetype/ChangeLog.22 @@ -199,7 +199,7 @@ * src/base/ftmac.c (read_lwfn): Catch integer overflow. * src/base/ftrfork.c (raccess_guess_darwin_hfsplus): Ditto. * src/base/ftutil.c: Remove special code for FT_STRICT_ALIASING. - (ft_mem_alloc. ft_mem_realloc, ft_mem_qrealloc): Rewrite. + (ft_mem_alloc, ft_mem_realloc, ft_mem_qrealloc): Rewrite. * include/freetype/ftstream.h (FT_FRAME_ENTER, FT_FRAME_EXIT, @@ -2301,7 +2301,7 @@ 2005-09-19 David Somers - * freetype2/src/sfnt/ttload.c (sfnt_dir_check): Modified to allow a + * src/sfnt/ttload.c (sfnt_dir_check): Modified to allow a font to have no `head' table if tables `SING' and `META' are present; this is to support `SING Glyphlet'. @@ -2320,9 +2320,9 @@ http://www.adobe.com/products/indesign/sing_gaiji.html - * freetype2/include/freetype/ttags.h (TTAG_SING, TTAG_META): New - macros for the OpenType tables `SING' and `META'. These two tables - are used in SING Glyphlet Format fonts. + * include/freetype/ttags.h (TTAG_SING, TTAG_META): New macros for + the OpenType tables `SING' and `META'. These two tables are used in + SING Glyphlet Format fonts. 2005-09-09 Werner Lemberg @@ -2808,7 +2808,7 @@ . loader->pp3.y and loader->pp4.y are in 26.6 format, not in font units. . As we use the glyph's cbox to calculate the top bearing now - there iss no need to adjust `top'. + there is no need to adjust `top'. 2005-06-15 Werner Lemberg @@ -2821,7 +2821,7 @@ ---------------------------------------------------------------------------- -Copyright 2005, 2006, 2007 by +Copyright 2005, 2006, 2007, 2008 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/lib/3rdparty/freetype/Jamfile b/lib/3rdparty/freetype/Jamfile index ad1341ed369..d8c1bbada29 100644 --- a/lib/3rdparty/freetype/Jamfile +++ b/lib/3rdparty/freetype/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 top Jamfile. # -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -194,7 +194,7 @@ rule RefDoc actions RefDoc { - python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.3.5 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h + python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.3.12 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h } RefDoc refdoc ; diff --git a/lib/3rdparty/freetype/README b/lib/3rdparty/freetype/README index 82d0003374a..282791ef087 100644 --- a/lib/3rdparty/freetype/README +++ b/lib/3rdparty/freetype/README @@ -9,8 +9,8 @@ is called `libttf'. They are *not* compatible! - FreeType 2.3.5 - ============== + FreeType 2.3.12 + =============== Please read the docs/CHANGES file, it contains IMPORTANT INFORMATION. @@ -26,9 +26,9 @@ and download one of the following files. - freetype-doc-2.3.5.tar.bz2 - freetype-doc-2.3.5.tar.gz - ftdoc235.zip + freetype-doc-2.3.12.tar.bz2 + freetype-doc-2.3.12.tar.gz + ftdoc2312.zip Bugs @@ -51,7 +51,7 @@ ---------------------------------------------------------------------- -Copyright 2006, 2007 by +Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/lib/3rdparty/freetype/README.CVS b/lib/3rdparty/freetype/README.git similarity index 62% rename from lib/3rdparty/freetype/README.CVS rename to lib/3rdparty/freetype/README.git index 63afddfbb52..bb36cf7b303 100644 --- a/lib/3rdparty/freetype/README.CVS +++ b/lib/3rdparty/freetype/README.git @@ -1,50 +1,46 @@ -The CVS archive doesn't contain pre-built configuration scripts for -UNIXish platforms. To generate them say - - sh autogen.sh - -which in turn depends on the following packages: - - automake (1.9.6) - libtool (1.5.22) - autoconf (2.59c) - -The versions given in parentheses are known to work. Newer versions -should work too, of course. Note that autogen.sh also sets up proper -file permissions for the `configure' and auxiliary scripts. - -A very common problem is that this script complains that the `aclocal' -program doesn't accept a `--force' option: - - generating `configure.ac' - running `aclocal -I . --force' - aclocal: unrecognized option -- `--force' - Try `aclocal --help' for more information. - error while running `aclocal -I . --force' - -This means that your version of the automake package is too old. -Please update it before trying to build FreeType. - - -For static builds which don't use platform specific optimizations, no -configure script is necessary at all; saying - - make setup ansi - make - -should work on all platforms which have GNU make (or makepp). - - ----------------------------------------------------------------------- - -Copyright 2005, 2006, 2007 by -David Turner, Robert Wilhelm, and Werner Lemberg. - -This file is part of the FreeType project, and may only be used, -modified, and distributed under the terms of the FreeType project -license, LICENSE.TXT. By continuing to use, modify, or distribute -this file you indicate that you have read the license and understand -and accept it fully. - - ---- end of README.CVS --- +The git archive doesn't contain pre-built configuration scripts for +UNIXish platforms. To generate them say + + sh autogen.sh + +which in turn depends on the following packages: + + automake (1.10.1) + libtool (2.2.4) + autoconf (2.62) + +The versions given in parentheses are known to work. Newer versions +should work too, of course. Note that autogen.sh also sets up proper +file permissions for the `configure' and auxiliary scripts. + +The autogen.sh script now checks the version of above three packages +whether they match the numbers above. Otherwise it will complain and +suggest either upgrading or using an environment variable to point to +a more recent version of the required tool(s). + +Note that `aclocal' is provided by the `automake' package on Linux, +and that `libtoolize' is called `glibtoolize' on Darwin (OS X). + + +For static builds which don't use platform specific optimizations, no +configure script is necessary at all; saying + + make setup ansi + make + +should work on all platforms which have GNU make (or makepp). + + +---------------------------------------------------------------------- + +Copyright 2005, 2006, 2007, 2008, 2009 by +David Turner, Robert Wilhelm, and Werner Lemberg. + +This file is part of the FreeType project, and may only be used, +modified, and distributed under the terms of the FreeType project +license, LICENSE.TXT. By continuing to use, modify, or distribute +this file you indicate that you have read the license and understand +and accept it fully. + + +--- end of README.CVS --- diff --git a/lib/3rdparty/freetype/autogen.sh b/lib/3rdparty/freetype/autogen.sh index d8fb5b2ec6d..c28a51c1323 100644 --- a/lib/3rdparty/freetype/autogen.sh +++ b/lib/3rdparty/freetype/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright 2005, 2006, 2007 by +# Copyright 2005, 2006, 2007, 2008, 2009, 2010 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,12 +20,121 @@ run () fi } +get_major_version () +{ + echo $1 | sed -e 's/\([0-9][0-9]*\)\..*/\1/g' +} + +get_minor_version () +{ + echo $1 | sed -e 's/[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g' +} + +get_patch_version () +{ + # tricky: some version numbers don't include a patch + # separated with a point, but something like 1.4-p6 + patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'` + if test "$patch" = "$1"; then + patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\-p\([0-9][0-9]*\).*/\1/g'` + # if there isn't any patch number, default to 0 + if test "$patch" = "$1"; then + patch=0 + fi + fi + echo $patch +} + +# $1: version to check +# $2: minimum version + +compare_to_minimum_version () +{ + MAJOR1=`get_major_version $1` + MAJOR2=`get_major_version $2` + if test $MAJOR1 -lt $MAJOR2; then + echo 0 + return + else + if test $MAJOR1 -gt $MAJOR2; then + echo 1 + return + fi + fi + + MINOR1=`get_minor_version $1` + MINOR2=`get_minor_version $2` + if test $MINOR1 -lt $MINOR2; then + echo 0 + return + else + if test $MINOR1 -gt $MINOR2; then + echo 1 + return + fi + fi + + PATCH1=`get_patch_version $1` + PATCH2=`get_patch_version $2` + if test $PATCH1 -lt $PATCH2; then + echo 0 + else + echo 1 + fi +} + +# check the version of a given tool against a minimum version number +# +# $1: tool path +# $2: tool usual name (e.g. `aclocal') +# $3: tool variable (e.g. `ACLOCAL') +# $4: minimum version to check against +# $5: option field index used to extract the tool version from the +# output of --version + +check_tool_version () +{ + field=$5 + # assume the output of "[TOOL] --version" is "toolname (GNU toolname foo bar) version" + if test "$field"x = x; then + field=3 # default to 3 for all GNU autotools, after filtering enclosed string + fi + version=`$1 --version | head -1 | sed 's/([^)]*)/()/g' | cut -d ' ' -f $field` + version_check=`compare_to_minimum_version $version $4` + if test "$version_check"x = 0x; then + echo "ERROR: Your version of the \`$2' tool is too old." + echo " Minimum version $4 is required (yours is version $version)." + echo " Please upgrade or use the $3 variable to point to a more recent one." + echo "" + exit 1 + fi +} + if test ! -f ./builds/unix/configure.raw; then echo "You must be in the same directory as \`autogen.sh'." echo "Bootstrapping doesn't work if srcdir != builddir." exit 1 fi +# On MacOS X, the GNU libtool is named `glibtool'. +HOSTOS=`uname` +LIBTOOLIZE=libtoolize +if test "$HOSTOS"x = Darwinx; then + LIBTOOLIZE=glibtoolize +fi + +if test "$ACLOCAL"x = x; then + ACLOCAL=aclocal +fi + +if test "$AUTOCONF"x = x; then + AUTOCONF=autoconf +fi + +check_tool_version $ACLOCAL aclocal ACLOCAL 1.10.1 +check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4 +check_tool_version $AUTOCONF autoconf AUTOCONF 2.62 + # This sets freetype_major, freetype_minor, and freetype_patch. eval `sed -nf version.sed include/freetype/freetype.h` @@ -38,17 +147,10 @@ cd builds/unix echo "generating \`configure.ac'" sed -e "s;@VERSION@;$freetype_major$freetype_minor$freetype_patch;" \ - < configure.raw > configure.ac - -# On MacOS X, the GNU libtool is named `glibtool'. -HOSTOS=`uname` -LIBTOOLIZE=libtoolize -if test "$HOSTOS"x = Darwinx; then - LIBTOOLIZE=glibtoolize -fi + < configure.raw > configure.ac run aclocal -I . --force -run $LIBTOOLIZE --force --copy +run $LIBTOOLIZE --force --copy --install run autoconf --force chmod +x mkinstalldirs diff --git a/lib/3rdparty/freetype/configure b/lib/3rdparty/freetype/configure index f251ae417a4..2efa2696797 100644 --- a/lib/3rdparty/freetype/configure +++ b/lib/3rdparty/freetype/configure @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2002, 2003, 2004, 2005, 2006 by +# Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,7 +21,7 @@ fi if test -z "`$GNUMAKE -v 2>/dev/null | grep GNU`"; then if test -z "`$GNUMAKE -v 2>/dev/null | grep makepp`"; then - echo "GNU make (>= 3.79.1) or makepp (>= 1.19) is required to build FreeType2." >&2 + echo "GNU make (>= 3.80) or makepp (>= 1.19) is required to build FreeType2." >&2 echo "Please try" >&2 echo " \`GNUMAKE= $0'." >&2 echo "or >&2" @@ -67,12 +67,25 @@ ft2_dir=`(dirname "$0") 2>/dev/null || abs_curr_dir=`pwd` abs_ft2_dir=`cd "$ft2_dir" && pwd` +# `--srcdir=' option can override abs_ft2_dir + +if test $# -gt 0; then + for x in "$@"; do + case x"$x" in + x--srcdir=*) + abs_ft2_dir=`echo $x | sed 's/^--srcdir=//'` ;; + esac + done +fi + # build a dummy Makefile if we are not building in the source tree if test "$abs_curr_dir" != "$abs_ft2_dir"; then mkdir reference - echo "Copying \`modules.cfg'" - cp $abs_ft2_dir/modules.cfg $abs_curr_dir + if test ! -r $abs_curr_dir/modules.cfg; then + echo "Copying \`modules.cfg'" + cp $abs_ft2_dir/modules.cfg $abs_curr_dir + fi echo "Generating \`Makefile'" echo "TOP_DIR := $abs_ft2_dir" > Makefile echo "OBJ_DIR := $abs_curr_dir" >> Makefile @@ -92,9 +105,16 @@ fi # call make CFG= -for x in ${1+"$@"}; do - CFG="$CFG \"$x\"" -done +# work around zsh bug which doesn't like `${1+"$@"}' +case $# in +0) ;; +*) for x in "$@"; do + case x"$x" in + x--srcdir=* ) CFG="$CFG '$x'/builds/unix" ;; + *) CFG="$CFG '$x'" ;; + esac + done ;; +esac CFG=$CFG $GNUMAKE setup unix # eof diff --git a/lib/3rdparty/freetype/devel/ftoption.h b/lib/3rdparty/freetype/devel/ftoption.h index 6cf1af23610..9c6c2fe4594 100644 --- a/lib/3rdparty/freetype/devel/ftoption.h +++ b/lib/3rdparty/freetype/devel/ftoption.h @@ -4,7 +4,8 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +86,9 @@ FT_BEGIN_HEADER /* */ /* This macro has no impact on the FreeType API, only on its */ /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ - /* the original size; the difference will be that each triplet of */ - /* subpixels has R=G=B. */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ /* */ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ @@ -112,7 +113,28 @@ FT_BEGIN_HEADER /* file `ftconfig.h' either statically or through the */ /* `configure' script on supported platforms. */ /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX /*************************************************************************/ @@ -163,7 +185,7 @@ FT_BEGIN_HEADER /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /*************************************************************************/ @@ -204,27 +226,27 @@ FT_BEGIN_HEADER /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ - /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ - /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* Undefine this macro if you do not want `psnames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table. */ /* */ - /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ @@ -240,12 +262,12 @@ FT_BEGIN_HEADER /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ - /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST @@ -291,10 +313,11 @@ FT_BEGIN_HEADER /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ - /* This allows FreeType to be used with the PostScript language, using */ - /* the GhostScript interpreter. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ /* */ -/* #define FT_CONFIG_OPTION_INCREMENTAL */ +#define FT_CONFIG_OPTION_INCREMENTAL /*************************************************************************/ @@ -375,6 +398,20 @@ FT_BEGIN_HEADER #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + /*************************************************************************/ /*************************************************************************/ @@ -418,7 +455,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ + /* `freetype/ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -436,6 +473,8 @@ FT_BEGIN_HEADER #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 /*************************************************************************/ @@ -466,9 +505,9 @@ FT_BEGIN_HEADER /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ /* of the TrueType bytecode interpreter is used that doesn't implement */ /* any of the patented opcodes and algorithms. Note that the */ - /* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */ - /* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, either define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ /* */ /* This macro is only useful for a small number of font files (mostly */ @@ -624,11 +663,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Compile autofit module with CJK script support. */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ /* */ #define AF_CONFIG_OPTION_CJK - /*************************************************************************/ /* */ /* Compile autofit module with Indic script support. */ @@ -648,15 +687,16 @@ FT_BEGIN_HEADER * is recommended to disable the macro since it reduces the library's code * size and activates a few memory-saving optimizations as well. */ -#undef FT_CONFIG_OPTION_OLD_INTERNALS +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* - * This variable is defined if either unpatented or native TrueType + * This macro is defined if either unpatented or native TrueType * hinting is requested by the definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING #elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING #define TT_USE_BYTECODE_INTERPRETER #endif diff --git a/lib/3rdparty/freetype/freetype.def b/lib/3rdparty/freetype/freetype.def index e6896e69e2b..1f5895f9b92 100644 --- a/lib/3rdparty/freetype/freetype.def +++ b/lib/3rdparty/freetype/freetype.def @@ -40,13 +40,19 @@ EXPORTS FT_Face_CheckTrueTypePatents FT_Face_SetUnpatentedHinting FT_FloorFix + FT_Get_Advance + FT_Get_Advances FT_Get_BDF_Charset_ID FT_Get_BDF_Property FT_Get_CMap_Format FT_Get_CMap_Language_ID FT_Get_Char_Index FT_Get_Charmap_Index + FT_Get_CID_From_Glyph_Index + FT_Get_CID_Is_Internally_CID_keyed + FT_Get_CID_Registry_Ordering_Supplement FT_Get_First_Char + FT_Get_FSType_Flags FT_Get_Glyph FT_Get_Glyph_Name FT_Get_Kerning diff --git a/lib/3rdparty/freetype/freetype.rbuild b/lib/3rdparty/freetype/freetype.rbuild index bf7709ede9d..5c41eb1d442 100644 --- a/lib/3rdparty/freetype/freetype.rbuild +++ b/lib/3rdparty/freetype/freetype.rbuild @@ -10,30 +10,28 @@ - - - setjmplongjmp.s - - - ftsystem.c - ftinit.c - ftdebug.c - _ftbase_ros.c + ftbase.c ftbbox.c - ftglyph.c ftbdf.c ftbitmap.c + ftdebug.c + ftgasp.c + ftglyph.c ftgxval.c + ftinit.c + ftlcdfil.c ftmm.c ftotval.c ftpatent.c ftpfr.c ftstroke.c ftsynth.c + ftsystem.c fttype1.c ftwinfnt.c + ftxf86.c autofit.c diff --git a/lib/3rdparty/freetype/i386/setjmplongjmp.s b/lib/3rdparty/freetype/i386/setjmplongjmp.s deleted file mode 100644 index d0e13a5b064..00000000000 --- a/lib/3rdparty/freetype/i386/setjmplongjmp.s +++ /dev/null @@ -1,91 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: FreeType implementation for ReactOS - * PURPOSE: Implementation of _setjmp/longjmp - * FILE: thirdparty/freetype/i386/setjmplongjmp.s - * PROGRAMMER: Ge van Geldorp (ge@gse.nl) - * NOTES: Copied from glibc. - * I have the feeling this could be implemented using the SEH - * routines, but if it's good enough for glibc it's propably - * good enough for me... - * The MingW headers define jmp_buf to be an array of 16 ints, - * based on the jmp_buf used by MSCVRT. We're using only 6 of - * them, so plenty of space. - */ - -#define JB_BX 0 -#define JB_SI 1 -#define JB_DI 2 -#define JB_BP 3 -#define JB_SP 4 -#define JB_PC 5 - -#define PCOFF 0 - -#define JMPBUF 4 - -/* - * int - * _setjmp(jmp_buf env); - * - * Parameters: - * [ESP+04h] - jmp_buf env - * Registers: - * None - * Returns: - * 0 - * Notes: - * Sets up the jmp_buf - */ -.globl __setjmp -__setjmp: - xorl %eax, %eax - movl JMPBUF(%esp), %edx - - /* Save registers. */ - movl %ebx, (JB_BX*4)(%edx) - movl %esi, (JB_SI*4)(%edx) - movl %edi, (JB_DI*4)(%edx) - leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ - movl %ecx, (JB_SP*4)(%edx) - movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */ - movl %ecx, (JB_PC*4)(%edx) - movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ - ret - -#define VAL 8 - -/* - * void - * longjmp(jmp_buf env, int value); - * - * Parameters: - * [ESP+04h] - jmp_buf setup by _setjmp - * [ESP+08h] - int value to return - * Registers: - * None - * Returns: - * Doesn't return - * Notes: - * Non-local goto - */ -.globl _longjmp -_longjmp: - movl JMPBUF(%esp), %ecx /* User's jmp_buf in %ecx. */ - - movl VAL(%esp), %eax /* Second argument is return value. */ - testl %eax, %eax - jnz 0f - incl %eax -0: - /* Save the return address now. */ - movl (JB_PC*4)(%ecx), %edx - /* Restore registers. */ - movl (JB_BX*4)(%ecx), %ebx - movl (JB_SI*4)(%ecx), %esi - movl (JB_DI*4)(%ecx), %edi - movl (JB_BP*4)(%ecx), %ebp - movl (JB_SP*4)(%ecx), %esp - /* Jump to saved PC. */ - jmp *%edx diff --git a/lib/3rdparty/freetype/include/freetype/config/ftconfig.h b/lib/3rdparty/freetype/include/freetype/config/ftconfig.h index 1547f5adb14..43d587e02b9 100644 --- a/lib/3rdparty/freetype/include/freetype/config/ftconfig.h +++ b/lib/3rdparty/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,6 @@ /* */ /*************************************************************************/ - #ifndef __FTCONFIG_H__ #define __FTCONFIG_H__ @@ -43,6 +42,7 @@ #include FT_CONFIG_OPTIONS_H #include FT_CONFIG_STANDARD_LIBRARY_H + FT_BEGIN_HEADER @@ -134,18 +134,78 @@ FT_BEGIN_HEADER #else #define FT_MACINTOSH 1 #endif + +#elif defined( __SC__ ) || defined( __MRC__ ) + /* Classic MacOS compilers */ +#include "ConditionalMacros.h" +#if TARGET_OS_MAC +#define FT_MACINTOSH 1 +#endif + #endif /*************************************************************************/ /* */ - /* IntN types */ + /*
*/ + /* basic_types */ /* */ - /* Used to guarantee the size of some specific integers. */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int16 */ + /* */ + /* */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt16 */ + /* */ + /* */ + /* A typedef for a 16bit unsigned integer type. */ /* */ - typedef signed short FT_Int16; typedef unsigned short FT_UInt16; + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int32 */ + /* */ + /* */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + /* */ + +#endif + #if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) typedef signed int FT_Int32; @@ -160,6 +220,7 @@ FT_BEGIN_HEADER #error "no 32bit type found -- please check your configuration files" #endif + /* look up an integer type that is at least 32 bits */ #if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) @@ -215,17 +276,12 @@ FT_BEGIN_HEADER #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ -#define FT_BEGIN_STMNT do { -#define FT_END_STMNT } while ( 0 ) -#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT - - /*************************************************************************/ /* */ /* A 64-bit data type will create compilation problems if you compile */ - /* in strict ANSI mode. To avoid them, we disable their use if */ - /* __STDC__ is defined. You can however ignore this rule by */ - /* defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* in strict ANSI mode. To avoid them, we disable its use if __STDC__ */ + /* is defined. You can however ignore this rule by defining the */ + /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ /* */ #if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) @@ -240,6 +296,115 @@ FT_BEGIN_HEADER #endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + +#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER + /* Provide assembler fragments for performance-critical functions. */ + /* These must be defined `static __inline__' with GCC. */ + +#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */ +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + __asm + { + smull t2, t, b, a /* (lo=t2,hi=t) = a*b */ + mov a, t, asr #31 /* a = (hi >> 31) */ + add a, a, #0x8000 /* a += 0x8000 */ + adds t2, t2, a /* t2 += a */ + adc t, t, #0 /* t += carry */ + mov a, t2, lsr #16 /* a = t2 >> 16 */ + orr a, a, t, lsl #16 /* a |= t << 16 */ + } + return a; + } + +#endif /* __CC_ARM || __ARMCC__ */ + + +#ifdef __GNUC__ + +#if defined( __arm__ ) && !defined( __thumb__ ) && \ + !( defined( __CC_ARM ) || defined( __ARMCC__ ) ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_arm + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_arm( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 t, t2; + + + asm __volatile__ ( + "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */ + "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */ + "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */ + "adds %1, %1, %0\n\t" /* %1 += %0 */ + "adc %2, %2, #0\n\t" /* %2 += carry */ + "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */ + "orr %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */ + : "=r"(a), "=&r"(t2), "=&r"(t) + : "r"(a), "r"(b) ); + return a; + } + +#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */ + +#if defined( i386 ) +#define FT_MULFIX_ASSEMBLER FT_MulFix_i386 + + /* documentation is in freetype.h */ + + static __inline__ FT_Int32 + FT_MulFix_i386( FT_Int32 a, + FT_Int32 b ) + { + register FT_Int32 result; + + + __asm__ __volatile__ ( + "imul %%edx\n" + "movl %%edx, %%ecx\n" + "sarl $31, %%ecx\n" + "addl $0x8000, %%ecx\n" + "addl %%ecx, %%eax\n" + "adcl $0, %%edx\n" + "shrl $16, %%eax\n" + "shll $16, %%edx\n" + "addl %%edx, %%eax\n" + : "=a"(result), "=d"(b) + : "a"(a), "d"(b) + : "%ecx", "cc" ); + return result; + } + +#endif /* i386 */ + +#endif /* __GNUC__ */ + +#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */ + + +#ifdef FT_CONFIG_OPTION_INLINE_MULFIX +#ifdef FT_MULFIX_ASSEMBLER +#define FT_MULFIX_INLINED FT_MULFIX_ASSEMBLER +#endif +#endif + + #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x diff --git a/lib/3rdparty/freetype/include/freetype/config/ftheader.h b/lib/3rdparty/freetype/include/freetype/config/ftheader.h index b957d05bedd..b63945dcbd3 100644 --- a/lib/3rdparty/freetype/include/freetype/config/ftheader.h +++ b/lib/3rdparty/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ /* */ /* */ /* The following macros are defined to the name of specific */ - /* FreeType 2 header files. They can be used directly in #include */ + /* FreeType~2 header files. They can be used directly in #include */ /* statements as in: */ /* */ /* { */ @@ -85,11 +85,11 @@ /* */ /* There are several reasons why we are now using macros to name */ /* public header files. The first one is that such macros are not */ - /* limited to the infamous 8.3 naming rule required by DOS (and */ + /* limited to the infamous 8.3~naming rule required by DOS (and */ /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ /* */ /* The second reason is that it allows for more flexibility in the */ - /* way FreeType 2 is installed on a given system. */ + /* way FreeType~2 is installed on a given system. */ /* */ /*************************************************************************/ @@ -103,7 +103,7 @@ * * @description: * A macro used in #include statements to name the file containing - * FreeType 2 configuration data. + * FreeType~2 configuration data. * */ #ifndef FT_CONFIG_CONFIG_H @@ -118,7 +118,7 @@ * * @description: * A macro used in #include statements to name the file containing - * FreeType 2 interface to the standard C library functions. + * FreeType~2 interface to the standard C library functions. * */ #ifndef FT_CONFIG_STANDARD_LIBRARY_H @@ -133,7 +133,7 @@ * * @description: * A macro used in #include statements to name the file containing - * FreeType 2 project-specific configuration options. + * FreeType~2 project-specific configuration options. * */ #ifndef FT_CONFIG_OPTIONS_H @@ -148,7 +148,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list of FreeType 2 modules that are statically linked to new library + * list of FreeType~2 modules that are statically linked to new library * instances in @FT_Init_FreeType. * */ @@ -156,6 +156,7 @@ #define FT_CONFIG_MODULES_H #endif + /* */ /* public headers */ @@ -166,7 +167,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * base FreeType 2 API. + * base FreeType~2 API. * */ #define FT_FREETYPE_H @@ -179,7 +180,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list of FreeType 2 error codes (and messages). + * list of FreeType~2 error codes (and messages). * * It is included by @FT_FREETYPE_H. * @@ -194,7 +195,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list of FreeType 2 module error offsets (and messages). + * list of FreeType~2 module error offsets (and messages). * */ #define FT_MODULE_ERRORS_H @@ -207,7 +208,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 interface to low-level operations (i.e., memory management + * FreeType~2 interface to low-level operations (i.e., memory management * and stream i/o). * * It is included by @FT_FREETYPE_H. @@ -239,7 +240,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * basic data types defined by FreeType 2. + * basic data types defined by FreeType~2. * * It is included by @FT_FREETYPE_H. * @@ -254,7 +255,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * list management API of FreeType 2. + * list management API of FreeType~2. * * (Most applications will never need to include this file.) * @@ -269,7 +270,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * scalable outline management API of FreeType 2. + * scalable outline management API of FreeType~2. * */ #define FT_OUTLINE_H @@ -295,7 +296,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * module management API of FreeType 2. + * module management API of FreeType~2. * */ #define FT_MODULE_H @@ -308,7 +309,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * renderer module management API of FreeType 2. + * renderer module management API of FreeType~2. * */ #define FT_RENDER_H @@ -321,7 +322,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * types and API specific to the Type 1 format. + * types and API specific to the Type~1 format. * */ #define FT_TYPE1_TABLES_H @@ -383,6 +384,20 @@ #define FT_BDF_H + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H + + /************************************************************************* * * @macro: @@ -468,7 +483,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * API of the optional FreeType 2 cache sub-system. + * API of the optional FreeType~2 cache sub-system. * */ #define FT_CACHE_H @@ -481,7 +496,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * `glyph image' API of the FreeType 2 cache sub-system. + * `glyph image' API of the FreeType~2 cache sub-system. * * It is used to define a cache for @FT_Glyph elements. You can also * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to @@ -501,7 +516,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * `small bitmaps' API of the FreeType 2 cache sub-system. + * `small bitmaps' API of the FreeType~2 cache sub-system. * * It is used to define a cache for small glyph bitmaps in a relatively * memory-efficient way. You can also use the API defined in @@ -522,7 +537,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * `charmap' API of the FreeType 2 cache sub-system. + * `charmap' API of the FreeType~2 cache sub-system. * * This macro is deprecated. Simply include @FT_CACHE_H to have all * charmap-based cache declarations. @@ -538,7 +553,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * Macintosh-specific FreeType 2 API. The latter is used to access + * Macintosh-specific FreeType~2 API. The latter is used to access * fonts embedded in resource forks. * * This header file must be explicitly included by client applications @@ -555,7 +570,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional multiple-masters management API of FreeType 2. + * optional multiple-masters management API of FreeType~2. * */ #define FT_MULTIPLE_MASTERS_H @@ -568,7 +583,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API which accesses embedded `name' strings in + * optional FreeType~2 API which accesses embedded `name' strings in * SFNT-based font formats (i.e., TrueType and OpenType). * */ @@ -582,7 +597,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API which validates OpenType tables (BASE, GDEF, + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, * GPOS, GSUB, JSTF). * */ @@ -596,7 +611,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * optional FreeType 2 API which validates TrueTypeGX/AAT tables (feat, + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, * mort, morx, bsln, just, kern, opbd, trak, prop). * */ @@ -610,7 +625,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which accesses PFR-specific data. + * FreeType~2 API which accesses PFR-specific data. * */ #define FT_PFR_H @@ -623,7 +638,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which provides functions to stroke outline paths. + * FreeType~2 API which provides functions to stroke outline paths. */ #define FT_STROKER_H @@ -635,7 +650,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which performs artificial obliquing and emboldening. + * FreeType~2 API which performs artificial obliquing and emboldening. */ #define FT_SYNTHESIS_H @@ -647,7 +662,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which provides functions specific to the XFree86 and + * FreeType~2 API which provides functions specific to the XFree86 and * X.Org X11 servers. */ #define FT_XFREE86_H @@ -660,7 +675,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which performs trigonometric computations (e.g., + * FreeType~2 API which performs trigonometric computations (e.g., * cosines and arc tangents). */ #define FT_TRIGONOMETRY_H @@ -673,11 +688,35 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which performs color filtering for subpixel rendering. + * FreeType~2 API which performs color filtering for subpixel rendering. */ #define FT_LCD_FILTER_H + /************************************************************************* + * + * @macro: + * FT_UNPATENTED_HINTING_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_UNPATENTED_HINTING_H + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_INCREMENTAL_H + + /************************************************************************* * * @macro: @@ -685,11 +724,23 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType 2 API which returns entries from the TrueType GASP table. + * FreeType~2 API which returns entries from the TrueType GASP table. */ #define FT_GASP_H + /************************************************************************* + * + * @macro: + * FT_ADVANCES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns individual and ranged glyph advances. + */ +#define FT_ADVANCES_H + + /* */ #define FT_ERROR_DEFINITIONS_H diff --git a/lib/3rdparty/freetype/include/freetype/config/ftmodule.h b/lib/3rdparty/freetype/include/freetype/config/ftmodule.h index d92b0ee6a1a..76d271a74b9 100644 --- a/lib/3rdparty/freetype/include/freetype/config/ftmodule.h +++ b/lib/3rdparty/freetype/include/freetype/config/ftmodule.h @@ -10,23 +10,23 @@ * */ -FT_USE_MODULE(autofit_module_class) -FT_USE_MODULE(tt_driver_class) -FT_USE_MODULE(t1_driver_class) -FT_USE_MODULE(cff_driver_class) -FT_USE_MODULE(t1cid_driver_class) -FT_USE_MODULE(pfr_driver_class) -FT_USE_MODULE(t42_driver_class) -FT_USE_MODULE(winfnt_driver_class) -FT_USE_MODULE(pcf_driver_class) -FT_USE_MODULE(psaux_module_class) -FT_USE_MODULE(psnames_module_class) -FT_USE_MODULE(pshinter_module_class) -FT_USE_MODULE(ft_raster1_renderer_class) -FT_USE_MODULE(sfnt_module_class) -FT_USE_MODULE(ft_smooth_renderer_class) -FT_USE_MODULE(ft_smooth_lcd_renderer_class) -FT_USE_MODULE(ft_smooth_lcdv_renderer_class) -FT_USE_MODULE(bdf_driver_class) +FT_USE_MODULE( FT_Module_Class, autofit_module_class ) +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Module_Class, psaux_module_class ) +FT_USE_MODULE( FT_Module_Class, psnames_module_class ) +FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) /* EOF */ diff --git a/lib/3rdparty/freetype/include/freetype/config/ftoption.h b/lib/3rdparty/freetype/include/freetype/config/ftoption.h index 5d99ae3c3c2..443c0d8bf4d 100644 --- a/lib/3rdparty/freetype/include/freetype/config/ftoption.h +++ b/lib/3rdparty/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,8 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,9 +86,9 @@ FT_BEGIN_HEADER /* */ /* This macro has no impact on the FreeType API, only on its */ /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ - /* the original size; the difference will be that each triplet of */ - /* subpixels has R=G=B. */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ /* */ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ @@ -112,7 +113,28 @@ FT_BEGIN_HEADER /* file `ftconfig.h' either statically or through the */ /* `configure' script on supported platforms. */ /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX /*************************************************************************/ @@ -163,7 +185,7 @@ FT_BEGIN_HEADER /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /*************************************************************************/ @@ -204,27 +226,27 @@ FT_BEGIN_HEADER /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ - /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ - /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* Undefine this macro if you do not want `psnames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table. */ /* */ - /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ @@ -240,12 +262,12 @@ FT_BEGIN_HEADER /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ - /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST @@ -291,8 +313,9 @@ FT_BEGIN_HEADER /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ - /* This allows FreeType to be used with the PostScript language, using */ - /* the GhostScript interpreter. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ /* */ /* #define FT_CONFIG_OPTION_INCREMENTAL */ @@ -375,6 +398,20 @@ FT_BEGIN_HEADER #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + /*************************************************************************/ /*************************************************************************/ @@ -418,7 +455,7 @@ FT_BEGIN_HEADER /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ + /* `freetype/ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES @@ -436,6 +473,8 @@ FT_BEGIN_HEADER #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 /*************************************************************************/ @@ -466,9 +505,9 @@ FT_BEGIN_HEADER /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ /* of the TrueType bytecode interpreter is used that doesn't implement */ /* any of the patented opcodes and algorithms. Note that the */ - /* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */ - /* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, either define */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ /* */ /* This macro is only useful for a small number of font files (mostly */ @@ -505,7 +544,7 @@ FT_BEGIN_HEADER /* ... */ /* } */ /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ +//#define TT_CONFIG_OPTION_UNPATENTED_HINTING /*************************************************************************/ @@ -624,7 +663,8 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Compile autofit module with CJK script support. */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ /* */ #define AF_CONFIG_OPTION_CJK @@ -632,7 +672,7 @@ FT_BEGIN_HEADER /* */ /* Compile autofit module with Indic script support. */ /* */ -/* #define AF_CONFIG_OPTION_INDIC */ +#define AF_CONFIG_OPTION_INDIC /* */ @@ -651,11 +691,12 @@ FT_BEGIN_HEADER /* - * This variable is defined if either unpatented or native TrueType + * This macro is defined if either unpatented or native TrueType * hinting is requested by the definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING #elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING #define TT_USE_BYTECODE_INTERPRETER #endif diff --git a/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h b/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h index f923f3e4cf8..30ec14e74ef 100644 --- a/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h +++ b/lib/3rdparty/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -54,12 +54,6 @@ /* In these case, `ftconfig.h' will refuse to compile anyway with a */ /* message like `couldn't find 32-bit type' or something similar. */ /* */ - /* IMPORTANT NOTE: We do not define aliases for heap management and */ - /* i/o routines (i.e. malloc/free/fopen/fread/...) */ - /* since these functions should all be encapsulated */ - /* by platform-specific implementations of */ - /* `ftsystem.c'. */ - /* */ /**********************************************************************/ @@ -67,6 +61,7 @@ #define FT_CHAR_BIT CHAR_BIT #define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX #define FT_ULONG_MAX ULONG_MAX @@ -124,8 +119,6 @@ #define ft_qsort qsort -#define ft_exit exit /* only used to exit from unhandled exceptions */ - /**********************************************************************/ /* */ diff --git a/lib/3rdparty/freetype/include/freetype/freetype.h b/lib/3rdparty/freetype/include/freetype/freetype.h index dbca087e5f0..942a740f00a 100644 --- a/lib/3rdparty/freetype/include/freetype/freetype.h +++ b/lib/3rdparty/freetype/include/freetype/freetype.h @@ -4,7 +4,8 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,14 +26,6 @@ #endif - /*************************************************************************/ - /* */ - /* The `raster' component duplicates some of the declarations in */ - /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */ - /* */ - /*************************************************************************/ - - #ifndef __FREETYPE_H__ #define __FREETYPE_H__ @@ -60,8 +53,8 @@ FT_BEGIN_HEADER /* */ /* */ /* FreeType assumes that structures allocated by the user and passed */ - /* as arguments are zeroed out except for the actual data. With */ - /* other words, it is recommended to use `calloc' (or variants of it) */ + /* as arguments are zeroed out except for the actual data. In other */ + /* words, it is recommended to use `calloc' (or variants of it) */ /* instead of `malloc' for allocation. */ /* */ /*************************************************************************/ @@ -86,10 +79,10 @@ FT_BEGIN_HEADER /* Base Interface */ /* */ /* */ - /* The FreeType 2 base font interface. */ + /* The FreeType~2 base font interface. */ /* */ /* */ - /* This section describes the public high-level API of FreeType 2. */ + /* This section describes the public high-level API of FreeType~2. */ /* */ /* */ /* FT_Library */ @@ -191,6 +184,15 @@ FT_BEGIN_HEADER /* FT_Set_Charmap */ /* FT_Get_Charmap_Index */ /* */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING */ + /* FT_FSTYPE_EDITABLE_EMBEDDING */ + /* FT_FSTYPE_NO_SUBSETTING */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY */ + /* */ + /* FT_Get_FSType_Flags */ + /* */ /*************************************************************************/ @@ -230,6 +232,10 @@ FT_BEGIN_HEADER /* vertAdvance :: */ /* Advance height for vertical layout. */ /* */ + /* */ + /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ + /* dimensions of the hinted glyph (in case hinting is applicable). */ + /* */ typedef struct FT_Glyph_Metrics_ { FT_Pos width; @@ -386,8 +392,8 @@ FT_BEGIN_HEADER /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ /* */ - /* The @FT_FaceRec details the publicly accessible fields of a given */ - /* face object. */ + /* See @FT_FaceRec for the publicly accessible fields of a given face */ + /* object. */ /* */ typedef struct FT_FaceRec_* FT_Face; @@ -416,8 +422,8 @@ FT_BEGIN_HEADER /* activated at any given time per face. */ /* */ /* */ - /* The @FT_SizeRec structure details the publicly accessible fields */ - /* of a given size object. */ + /* See @FT_SizeRec for the publicly accessible fields of a given size */ + /* object. */ /* */ typedef struct FT_SizeRec_* FT_Size; @@ -429,7 +435,7 @@ FT_BEGIN_HEADER /* */ /* */ /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any one of the glyphs contained in its parent */ + /* is possible to load any of the glyphs contained in its parent */ /* face. */ /* */ /* In other words, each time you call @FT_Load_Glyph or */ @@ -438,7 +444,7 @@ FT_BEGIN_HEADER /* other control information. */ /* */ /* */ - /* @FT_GlyphSlotRec details the publicly accessible glyph fields. */ + /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ /* */ typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; @@ -469,8 +475,8 @@ FT_BEGIN_HEADER /* the list and automatically activates it. */ /* */ /* */ - /* The @FT_CharMapRec details the publicly accessible fields of a */ - /* given character map. */ + /* See @FT_CharMapRec for the publicly accessible fields of a given */ + /* character map. */ /* */ typedef struct FT_CharMapRec_* FT_CharMap; @@ -485,7 +491,7 @@ FT_BEGIN_HEADER /* used to define `encoding' identifiers (see @FT_Encoding). */ /* */ /* */ - /* Since many 16bit compilers don't like 32bit enumerations, you */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ /* should redefine this macro in case of problems to something like */ /* this: */ /* */ @@ -518,131 +524,132 @@ FT_BEGIN_HEADER /* */ /* Despite the name, this enumeration lists specific character */ /* repertories (i.e., charsets), and not text encoding methods (e.g., */ - /* UTF-8, UTF-16, GB2312_EUC, etc.). */ - /* */ - /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ - /* all character codes must be expressed as FT_Longs. */ + /* UTF-8, UTF-16, etc.). */ /* */ /* Other encodings might be defined in the future. */ /* */ /* */ - /* FT_ENCODING_NONE :: */ - /* The encoding value 0 is reserved. */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ /* */ - /* FT_ENCODING_UNICODE :: */ - /* Corresponds to the Unicode character set. This value covers */ - /* all versions of the Unicode repertoire, including ASCII and */ - /* Latin-1. Most fonts include a Unicode charmap, but not all */ - /* of them. */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ /* */ - /* FT_ENCODING_MS_SYMBOL :: */ - /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols in the 32..255 character code range. For */ - /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ /* */ - /* FT_ENCODING_SJIS :: */ - /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://langsupport.japanreference.com/encoding.shtml'. */ - /* See note on multi-byte encodings below. */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see `http://www.ceviz.net/symbol.htm'. */ /* */ - /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ - /* used in mainland China. */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* See note on multi-byte encodings below. */ /* */ - /* FT_ENCODING_BIG5 :: */ - /* Corresponds to an encoding system for Traditional Chinese as used */ - /* in Taiwan and Hong Kong. */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ /* */ - /* FT_ENCODING_WANSUNG :: */ - /* Corresponds to the Korean encoding system known as Wansung. */ - /* For more information see */ - /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as */ + /* used in Taiwan and Hong Kong. */ /* */ - /* FT_ENCODING_JOHAB :: */ - /* The Korean standard character set (KS C-5601-1992), which */ - /* corresponds to MS Windows code page 1361. This character set */ - /* includes all possible Hangeul character combinations. */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `http://www.microsoft.com/typography/unicode/949.txt'. */ /* */ - /* FT_ENCODING_ADOBE_LATIN_1 :: */ - /* Corresponds to a Latin-1 encoding as defined in a Type 1 */ - /* Postscript font. It is limited to 256 character codes. */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ /* */ - /* FT_ENCODING_ADOBE_STANDARD :: */ - /* Corresponds to the Adobe Standard encoding, as found in Type 1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ /* */ - /* FT_ENCODING_ADOBE_EXPERT :: */ - /* Corresponds to the Adobe Expert encoding, as found in Type 1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ /* */ - /* FT_ENCODING_ADOBE_CUSTOM :: */ - /* Corresponds to a custom encoding, as found in Type 1, CFF, and */ - /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ /* */ - /* FT_ENCODING_APPLE_ROMAN :: */ - /* Corresponds to the 8-bit Apple roman encoding. Many TrueType and */ - /* OpenType fonts contain a charmap for this encoding, since older */ - /* versions of Mac OS are able to use it. */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ - /* FT_ENCODING_OLD_LATIN_2 :: */ - /* This value is deprecated and was never used nor reported by */ - /* FreeType. Don't use or test for it. */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ + /* and OpenType fonts contain a charmap for this encoding, since */ + /* older versions of Mac OS are able to use it. */ /* */ - /* FT_ENCODING_MS_SJIS :: */ - /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ /* */ - /* FT_ENCODING_MS_GB2312 :: */ - /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ /* */ - /* FT_ENCODING_MS_BIG5 :: */ - /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ /* */ - /* FT_ENCODING_MS_WANSUNG :: */ - /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ /* */ - /* FT_ENCODING_MS_JOHAB :: */ - /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ /* */ /* */ - /* By default, FreeType automatically synthetizes a Unicode charmap */ - /* for Postscript fonts, using their glyph names dictionaries. */ - /* However, it also reports the encodings defined explicitly in the */ - /* font file, for the cases when they are needed, with the Adobe */ - /* values as well. */ + /* By default, FreeType automatically synthesizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ /* */ - /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ - /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ - /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out which */ - /* encoding is really present. If, for example, the `cs_registry' */ - /* field is `KOI8' and the `cs_encoding' field is `R', the font is */ - /* encoded in KOI8-R. */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ /* */ - /* FT_ENCODING_NONE is always set (with a single exception) by the */ - /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ - /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ - /* which encoding is really present. For example, */ - /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ - /* Russian). */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ /* */ - /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ - /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ - /* FT_ENCODING_APPLE_ROMAN). */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ /* */ - /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function c */ - /* @FT_Get_CMap_Language_ID to query the Mac language ID which may be */ - /* needed to be able to distinguish Apple encoding variants. See */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID which may */ + /* be needed to be able to distinguish Apple encoding variants. See */ /* */ - /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ /* */ - /* to get an idea how to do that. Basically, if the language ID is 0, */ - /* don't use it, otherwise subtract 1 from the language ID. Then */ - /* examine `encoding_id'. If, for example, `encoding_id' is */ - /* @TT_MAC_ID_ROMAN and the language ID (minus 1) is */ - /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ - /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ - /* variant the Arabic encoding. */ + /* to get an idea how to do that. Basically, if the language ID */ + /* is~0, don't use it, otherwise subtract 1 from the language ID. */ + /* Then examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ /* */ typedef enum FT_Encoding_ { @@ -753,7 +760,7 @@ FT_BEGIN_HEADER /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ /* model private data of a given @FT_Face object. */ /* */ - /* This structure might change between releases of FreeType 2 and is */ + /* This structure might change between releases of FreeType~2 and is */ /* not generally available to client applications. */ /* */ typedef struct FT_Face_InternalRec_* FT_Face_Internal; @@ -774,7 +781,7 @@ FT_BEGIN_HEADER /* a font file. */ /* */ /* face_index :: The index of the face in the font file. It */ - /* is set to 0 if there is only one face in */ + /* is set to~0 if there is only one face in */ /* the font file. */ /* */ /* face_flags :: A set of bit flags that give important */ @@ -790,6 +797,9 @@ FT_BEGIN_HEADER /* `num_fixed_sizes'), it is set to the number */ /* of outline glyphs. */ /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ /* family_name :: The face's family name. This is an ASCII */ /* string, usually in English, which describes */ /* the typeface's family (like `Times New */ @@ -799,6 +809,8 @@ FT_BEGIN_HEADER /* provide localized and Unicode versions of */ /* this string. Applications should use the */ /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ /* */ /* style_name :: The face's style name. This is an ASCII */ /* string, usually in English, which describes */ @@ -836,9 +848,13 @@ FT_BEGIN_HEADER /* descender'. Only relevant for scalable */ /* formats. */ /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ /* units_per_EM :: The number of font units per EM square for */ /* this face. This is typically 2048 for */ - /* TrueType fonts, and 1000 for Type 1 fonts. */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ /* Only relevant for scalable formats. */ /* */ /* ascender :: The typographic ascender of the face, */ @@ -874,7 +890,7 @@ FT_BEGIN_HEADER /* scalable formats. */ /* */ /* underline_position :: The position, in font units, of the */ - /* underline line for this face. It's the */ + /* underline line for this face. It is the */ /* center of the underlining stem. Only */ /* relevant for scalable formats. */ /* */ @@ -889,8 +905,8 @@ FT_BEGIN_HEADER /* charmap :: The current active charmap for this face. */ /* */ /* */ - /* Fields may be changed after a call to @FT_Attach_File or */ - /* @FT_Attach_Stream. */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ /* */ typedef struct FT_FaceRec_ { @@ -1019,6 +1035,36 @@ FT_BEGIN_HEADER /* the SFNT `gasp' table only if the native TrueType hinting engine */ /* (with the bytecode interpreter) is available and active. */ /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts which are in an SFNT wrapper don't */ + /* have this flag set since the glyphs are accessed in the normal */ + /* way (using contiguous indices); the `CID-ness' isn't visible to */ + /* the application. */ + /* */ + /* FT_FACE_FLAG_TRICKY :: */ + /* Set if the font is `tricky', this is, it always needs the */ + /* font format's native hinting engine to get a reasonable result. */ + /* A typical example is the Chinese font `mingli.ttf' which uses */ + /* TrueType bytecode instructions to move and scale all of its */ + /* subglyphs. */ + /* */ + /* It is not possible to autohint such fonts using */ + /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ + /* @FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING */ + /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ + /* probably never want this except for demonstration purposes. */ + /* */ + /* Currently, there are six TrueType fonts in the list of tricky */ + /* fonts; they are hard-coded in file `ttobjs.c'. */ + /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) @@ -1031,8 +1077,8 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) #define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) #define FT_FACE_FLAG_HINTER ( 1L << 11 ) - - /* */ +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) +#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) /************************************************************************* @@ -1087,7 +1133,7 @@ FT_BEGIN_HEADER * * @description: * A macro that returns true whenever a face object contains a scalable - * font face (true for TrueType, Type 1, Type 42, CID, OpenType/CFF, + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, * and PFR font formats. * */ @@ -1143,8 +1189,6 @@ FT_BEGIN_HEADER #define FT_HAS_FIXED_SIZES( face ) \ ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) - /* */ - /************************************************************************* * @@ -1187,9 +1231,41 @@ FT_BEGIN_HEADER ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /************************************************************************* + * + * @macro: + * FT_IS_TRICKY( face ) + * + * @description: + * A macro that returns true whenever a face represents a `tricky' font. + * See the discussion of @FT_FACE_FLAG_TRICKY for more details. + * + */ +#define FT_IS_TRICKY( face ) \ + ( face->face_flags & FT_FACE_FLAG_TRICKY ) + + /*************************************************************************/ /* */ - /* */ + /* */ /* FT_STYLE_FLAG_XXX */ /* */ /* */ @@ -1198,11 +1274,17 @@ FT_BEGIN_HEADER /* */ /* */ /* FT_STYLE_FLAG_ITALIC :: */ - /* Indicates that a given face is italicized. */ + /* Indicates that a given face style is italic or oblique. */ /* */ /* FT_STYLE_FLAG_BOLD :: */ /* Indicates that a given face is bold. */ /* */ + /* */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ #define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) #define FT_STYLE_FLAG_BOLD ( 1 << 1 ) @@ -1214,7 +1296,7 @@ FT_BEGIN_HEADER /* */ /* */ /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ - /* model private data of a given FT_Size object. */ + /* model private data of a given @FT_Size object. */ /* */ typedef struct FT_Size_InternalRec_* FT_Size_Internal; @@ -1345,7 +1427,7 @@ FT_BEGIN_HEADER /* */ /* */ /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ - /* model private data of a given FT_GlyphSlot object. */ + /* model private data of a given @FT_GlyphSlot object. */ /* */ typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; @@ -1400,8 +1482,13 @@ FT_BEGIN_HEADER /* important to perform correct WYSIWYG layout. */ /* Only relevant for outline glyphs. */ /* */ - /* advance :: This is the transformed advance width for the */ - /* glyph. */ + /* advance :: This shorthand is, depending on */ + /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ + /* advance width for the glyph (in 26.6 */ + /* fractional pixel format). As specified with */ + /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ + /* `horiAdvance' or the `vertAdvance' value of */ + /* `metrics' field. */ /* */ /* format :: This field indicates the format of the image */ /* contained in the glyph slot. Typically */ @@ -1425,7 +1512,7 @@ FT_BEGIN_HEADER /* bitmap_top :: This is the bitmap's top bearing expressed in */ /* integer pixels. Remember that this is the */ /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y-coordinates being */ + /* glyph scanline, upwards y~coordinates being */ /* *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ @@ -1448,7 +1535,7 @@ FT_BEGIN_HEADER /* */ /* control_data :: Certain font drivers can also return the */ /* control data for a given glyph image (e.g. */ - /* TrueType bytecode, Type 1 charstrings, etc.). */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ /* This field is a pointer to such data. */ /* */ /* control_len :: This is the length in bytes of the control */ @@ -1470,15 +1557,15 @@ FT_BEGIN_HEADER /* */ /* If @FT_Load_Glyph is called with default flags (see */ /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ - /* its native format (e.g., an outline glyph for TrueType and Type 1 */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ /* formats). */ /* */ /* This image can later be converted into a bitmap by calling */ /* @FT_Render_Glyph. This function finds the current renderer for */ - /* the native image's format then invokes it. */ + /* the native image's format, then invokes it. */ /* */ /* The renderer is in charge of transforming the native image through */ - /* the slot's face transformation fields, then convert it into a */ + /* the slot's face transformation fields, then converting it into a */ /* bitmap that is returned in `slot->bitmap'. */ /* */ /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ @@ -1573,7 +1660,12 @@ FT_BEGIN_HEADER /* alibrary :: A handle to a new library object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ + /* */ + /* */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ /* */ FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary ); @@ -1592,7 +1684,7 @@ FT_BEGIN_HEADER /* library :: A handle to the target library object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_FreeType( FT_Library library ); @@ -1608,26 +1700,26 @@ FT_BEGIN_HEADER /* @FT_Open_Args structure. */ /* */ /* */ - /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ /* */ - /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ /* */ - /* FT_OPEN_PATHNAME :: Create a new input stream from a C */ - /* path name. */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ /* */ - /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ /* */ - /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ /* */ - /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ + /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ /* */ - /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ + /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ /* */ - /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ + /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ /* */ - /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ + /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ /* */ - /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ + /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ /* */ /* */ /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ @@ -1652,8 +1744,8 @@ FT_BEGIN_HEADER /* FT_Parameter */ /* */ /* */ - /* A simple structure used to pass more or less generic parameters */ - /* to @FT_Open_Face. */ + /* A simple structure used to pass more or less generic parameters to */ + /* @FT_Open_Face. */ /* */ /* */ /* tag :: A four-byte identification tag. */ @@ -1661,7 +1753,8 @@ FT_BEGIN_HEADER /* data :: A pointer to the parameter data. */ /* */ /* */ - /* The ID and function of parameters are driver-specific. */ + /* The ID and function of parameters are driver-specific. See the */ + /* various FT_PARAM_TAG_XXX flags for more information. */ /* */ typedef struct FT_Parameter_ { @@ -1695,7 +1788,7 @@ FT_BEGIN_HEADER /* */ /* driver :: This field is exclusively used by @FT_Open_Face; */ /* it simply specifies the font driver to use to open */ - /* the face. If set to 0, FreeType tries to load the */ + /* the face. If set to~0, FreeType tries to load the */ /* face with each one of the drivers in its list. */ /* */ /* num_params :: The number of extra parameters. */ @@ -1726,7 +1819,7 @@ FT_BEGIN_HEADER /* `num_params' and `params' is used. They are ignored otherwise. */ /* */ /* Ideally, both the `pathname' and `params' fields should be tagged */ - /* as `const'; this is missing for API backwards compatibility. With */ + /* as `const'; this is missing for API backwards compatibility. In */ /* other words, applications should treat them as read-only. */ /* */ typedef struct FT_Open_Args_ @@ -1758,7 +1851,7 @@ FT_BEGIN_HEADER /* pathname :: A path to the font file. */ /* */ /* face_index :: The index of the face within the font. The first */ - /* face has index 0. */ + /* face has index~0. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ @@ -1766,7 +1859,7 @@ FT_BEGIN_HEADER /* See @FT_Open_Face for more details. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_New_Face( FT_Library library, @@ -1793,7 +1886,7 @@ FT_BEGIN_HEADER /* file_size :: The size of the memory chunk used by the font data. */ /* */ /* face_index :: The index of the face within the font. The first */ - /* face has index 0. */ + /* face has index~0. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ @@ -1801,7 +1894,7 @@ FT_BEGIN_HEADER /* See @FT_Open_Face for more details. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* You must not deallocate the memory before calling @FT_Done_Face. */ @@ -1831,7 +1924,7 @@ FT_BEGIN_HEADER /* be filled by the caller. */ /* */ /* face_index :: The index of the face within the font. The first */ - /* face has index 0. */ + /* face has index~0. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ @@ -1839,7 +1932,7 @@ FT_BEGIN_HEADER /* See note below. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* Unlike FreeType 1.x, this function automatically creates a glyph */ @@ -1848,7 +1941,7 @@ FT_BEGIN_HEADER /* */ /* FT_Open_Face can be used to quickly check whether the font */ /* format of a given font resource is supported by FreeType. If the */ - /* `face_index' field is negative, the function's return value is 0 */ + /* `face_index' field is negative, the function's return value is~0 */ /* if the font format is recognized, or non-zero otherwise; */ /* the function returns a more or less empty face handle in `*aface' */ /* (if `aface' isn't NULL). The only useful field in this special */ @@ -1881,7 +1974,7 @@ FT_BEGIN_HEADER /* filepathname :: The pathname. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Attach_File( FT_Face face, @@ -1896,7 +1989,7 @@ FT_BEGIN_HEADER /* */ /* `Attach' data to a face object. Normally, this is used to read */ /* additional information for the face object. For example, you can */ - /* attach an AFM file that comes with a Type 1 font to get the */ + /* attach an AFM file that comes with a Type~1 font to get the */ /* kerning values and other metrics. */ /* */ /* */ @@ -1907,7 +2000,7 @@ FT_BEGIN_HEADER /* the caller. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* The meaning of the `attach' (i.e., what really happens when the */ @@ -1936,7 +2029,7 @@ FT_BEGIN_HEADER /* face :: A handle to a target face object. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Face( FT_Face face ); @@ -1958,7 +2051,7 @@ FT_BEGIN_HEADER /* `available_sizes' field of @FT_FaceRec structure. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, @@ -2044,8 +2137,8 @@ FT_BEGIN_HEADER /* value. */ /* */ /* */ - /* If `width' is zero, then the horizontal scaling value is set */ - /* equal to the vertical scaling value, and vice versa. */ + /* If `width' is zero, then the horizontal scaling value is set equal */ + /* to the vertical scaling value, and vice versa. */ /* */ typedef struct FT_Size_RequestRec_ { @@ -2055,7 +2148,18 @@ FT_BEGIN_HEADER FT_UInt horiResolution; FT_UInt vertResolution; - } FT_Size_RequestRec, *FT_Size_Request; + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Size_Request */ + /* */ + /* */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; /*************************************************************************/ @@ -2073,7 +2177,7 @@ FT_BEGIN_HEADER /* req :: A pointer to a @FT_Size_RequestRec. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* Although drivers may select the bitmap strike matching the */ @@ -2108,7 +2212,7 @@ FT_BEGIN_HEADER /* vert_resolution :: The vertical resolution in dpi. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* If either the character width or height is zero, it is set equal */ @@ -2120,7 +2224,8 @@ FT_BEGIN_HEADER /* A character width or height smaller than 1pt is set to 1pt; if */ /* both resolution values are zero, they are set to 72dpi. */ /* */ - + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Char_Size( FT_Face face, FT_F26Dot6 char_width, @@ -2147,7 +2252,7 @@ FT_BEGIN_HEADER /* pixel_height :: The nominal height, in pixels. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, @@ -2180,12 +2285,17 @@ FT_BEGIN_HEADER /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* The loaded glyph may be transformed. See @FT_Set_Transform for */ /* the details. */ /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values which */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, @@ -2216,7 +2326,7 @@ FT_BEGIN_HEADER /* whether to hint the outline, etc). */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ @@ -2238,7 +2348,7 @@ FT_BEGIN_HEADER * * @values: * FT_LOAD_DEFAULT :: - * Corresponding to 0, this value is used as the default glyph load + * Corresponding to~0, this value is used as the default glyph load * operation. In this case, the following happens: * * 1. FreeType looks for a bitmap for the glyph corresponding to the @@ -2328,10 +2438,10 @@ FT_BEGIN_HEADER * FT_LOAD_MONOCHROME :: * This flag is used with @FT_LOAD_RENDER to indicate that you want to * render an outline glyph to a 1-bit monochrome bitmap glyph, with - * 8 pixels packed into each byte of the bitmap data. + * 8~pixels packed into each byte of the bitmap data. * * Note that this has no effect on the hinting algorithm used. You - * should use @FT_LOAD_TARGET_MONO instead so that the + * should rather use @FT_LOAD_TARGET_MONO so that the * monochrome-optimized hinting algorithm is used. * * FT_LOAD_LINEAR_DESIGN :: @@ -2350,8 +2460,12 @@ FT_BEGIN_HEADER * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be * used at all. * + * See the description of @FT_FACE_FLAG_TRICKY for a special exception + * (affecting only a handful of Asian fonts). + * * Besides deciding which hinter to use, you can also decide which * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + * */ #define FT_LOAD_DEFAULT 0x0 #define FT_LOAD_NO_SCALE 0x1 @@ -2367,13 +2481,14 @@ FT_BEGIN_HEADER #define FT_LOAD_IGNORE_TRANSFORM 0x800 #define FT_LOAD_MONOCHROME 0x1000 #define FT_LOAD_LINEAR_DESIGN 0x2000 - - /* temporary hack! */ -#define FT_LOAD_SBITS_ONLY 0x4000 #define FT_LOAD_NO_AUTOHINT 0x8000U /* */ + /* used internally only by certain font drivers! */ +#define FT_LOAD_ADVANCE_ONLY 0x100 +#define FT_LOAD_SBITS_ONLY 0x4000 + /************************************************************************** * @@ -2401,7 +2516,7 @@ FT_BEGIN_HEADER * FT_LOAD_TARGET_LIGHT :: * A lighter hinting algorithm for non-monochrome modes. Many * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS X. + * shape. A bit like rendering on Mac OS~X. * * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. * @@ -2437,30 +2552,29 @@ FT_BEGIN_HEADER * * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); * } + * */ +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) -#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) - -#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) -#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) -#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) -#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) -#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) - /* + /************************************************************************** + * * @macro: * FT_LOAD_TARGET_MODE * * @description: * Return the @FT_Render_Mode corresponding to a given * @FT_LOAD_TARGET_XXX value. + * */ - #define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) - /* */ - /*************************************************************************/ /* */ @@ -2476,9 +2590,9 @@ FT_BEGIN_HEADER /* face :: A handle to the source face object. */ /* */ /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use 0 for the null */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ /* vector. */ /* */ /* */ @@ -2503,17 +2617,19 @@ FT_BEGIN_HEADER /* */ /* */ /* An enumeration type that lists the render modes supported by */ - /* FreeType 2. Each mode corresponds to a specific type of scanline */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ /* conversion performed on the outline. */ /* */ - /* For bitmap fonts the `bitmap->pixel_mode' field in the */ - /* @FT_GlyphSlotRec structure gives the format of the returned */ - /* bitmap. */ + /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ + /* field in the @FT_GlyphSlotRec structure gives the format of the */ + /* returned bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ /* */ /* */ /* FT_RENDER_MODE_NORMAL :: */ /* This is the default render mode; it corresponds to 8-bit */ - /* anti-aliased bitmaps, using 256 levels of opacity. */ + /* anti-aliased bitmaps. */ /* */ /* FT_RENDER_MODE_LIGHT :: */ /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ @@ -2522,24 +2638,32 @@ FT_BEGIN_HEADER /* @FT_LOAD_TARGET_XXX for details. */ /* */ /* FT_RENDER_MODE_MONO :: */ - /* This mode corresponds to 1-bit bitmaps. */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ /* */ /* FT_RENDER_MODE_LCD :: */ /* This mode corresponds to horizontal RGB and BGR sub-pixel */ - /* displays, like LCD-screens. It produces 8-bit bitmaps that are */ - /* 3 times the width of the original glyph outline in pixels, and */ + /* displays like LCD screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ /* which use the @FT_PIXEL_MODE_LCD mode. */ /* */ /* FT_RENDER_MODE_LCD_V :: */ /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ /* (like PDA screens, rotated LCD displays, etc.). It produces */ - /* 8-bit bitmaps that are 3 times the height of the original */ + /* 8-bit bitmaps that are 3~times the height of the original */ /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ /* */ /* */ - /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph are */ - /* _not_ _filtered_ to reduce color-fringes. It is up to the caller */ - /* to perform this pass. */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + /* The selected render mode only affects vector glyphs of a font. */ + /* Embedded bitmaps often have a different pixel mode like */ + /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ + /* them into 8-bit pixmaps. */ /* */ typedef enum FT_Render_Mode_ { @@ -2564,8 +2688,8 @@ FT_BEGIN_HEADER /* @FT_Render_Mode values instead. */ /* */ /* */ - /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ - /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ + /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ + /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ /* */ #define ft_render_mode_normal FT_RENDER_MODE_NORMAL #define ft_render_mode_mono FT_RENDER_MODE_MONO @@ -2591,7 +2715,7 @@ FT_BEGIN_HEADER /* list of possible values. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, @@ -2609,7 +2733,7 @@ FT_BEGIN_HEADER /* */ /* */ /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ - /* distances (value is 0). */ + /* distances (value is~0). */ /* */ /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ /* distances. */ @@ -2687,7 +2811,7 @@ FT_BEGIN_HEADER /* and in pixels for fixed-sizes formats. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* Only horizontal layouts (left-to-right & right-to-left) are */ @@ -2712,17 +2836,17 @@ FT_BEGIN_HEADER /* Return the track kerning for a given face object at a given size. */ /* */ /* */ - /* face :: A handle to a source face object. */ + /* face :: A handle to a source face object. */ /* */ - /* point_size :: The point size in 16.16 fractional points. */ + /* point_size :: The point size in 16.16 fractional points. */ /* */ - /* degree :: The degree of tightness. */ + /* degree :: The degree of tightness. */ /* */ /* */ - /* akerning :: The kerning in 16.16 fractional points. */ + /* akerning :: The kerning in 16.16 fractional points. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Track_Kerning( FT_Face face, @@ -2738,7 +2862,7 @@ FT_BEGIN_HEADER /* */ /* */ /* Retrieve the ASCII name of a given glyph in a face. This only */ - /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns 1. */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ /* */ /* */ /* face :: A handle to a source face object. */ @@ -2753,12 +2877,12 @@ FT_BEGIN_HEADER /* copied to. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* An error is returned if the face doesn't provide glyph names or if */ /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' is set to 0 to indicate an empty name. */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ /* */ /* The glyph name is truncated to fit within the buffer if it is too */ /* long. The returned string is always zero-terminated. */ @@ -2780,14 +2904,14 @@ FT_BEGIN_HEADER /* FT_Get_Postscript_Name */ /* */ /* */ - /* Retrieve the ASCII Postscript name of a given face, if available. */ - /* This only works with Postscript and TrueType fonts. */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ /* */ /* */ /* face :: A handle to the source face object. */ /* */ /* */ - /* A pointer to the face's Postscript name. NULL if unavailable. */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ /* */ /* */ /* The returned pointer is owned by the face and is destroyed with */ @@ -2813,7 +2937,7 @@ FT_BEGIN_HEADER /* encoding :: A handle to the selected encoding. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* This function returns an error if no charmap in the face */ @@ -2821,7 +2945,8 @@ FT_BEGIN_HEADER /* */ /* Because many fonts contain more than a single cmap for Unicode */ /* encoding, this function has some special code to select the one */ - /* which covers Unicode best. It is thus preferable to */ + /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ + /* is preferred to a UCS-2 cmap). It is thus preferable to */ /* @FT_Set_Charmap in this case. */ /* */ FT_EXPORT( FT_Error ) @@ -2844,13 +2969,15 @@ FT_BEGIN_HEADER /* charmap :: A handle to the selected charmap. */ /* */ /* */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* */ /* This function returns an error if the charmap is not part of */ /* the face (i.e., if it is not listed in the `face->charmaps' */ /* table). */ /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Charmap( FT_Face face, FT_CharMap charmap ); @@ -2892,13 +3019,13 @@ FT_BEGIN_HEADER /* charcode :: The character code. */ /* */ /* */ - /* The glyph index. 0 means `undefined character code'. */ + /* The glyph index. 0~means `undefined character code'. */ /* */ /* */ /* If you use FreeType to manipulate the contents of font files */ /* directly, be aware that the glyph index returned by this function */ /* doesn't always correspond to the internal indices used within */ - /* the file. This is done to ensure that value 0 always corresponds */ + /* the file. This is done to ensure that value~0 always corresponds */ /* to the `missing glyph'. */ /* */ FT_EXPORT( FT_UInt ) @@ -2920,7 +3047,7 @@ FT_BEGIN_HEADER /* face :: A handle to the source face object. */ /* */ /* */ - /* agindex :: Glyph index of first character code. 0 if charmap is */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ /* empty. */ /* */ /* */ @@ -2945,9 +3072,9 @@ FT_BEGIN_HEADER /* } */ /* } */ /* */ - /* Note that `*agindex' is set to 0 if the charmap is empty. The */ - /* result itself can be 0 in two cases: if the charmap is empty or */ - /* when the value 0 is the first valid character code. */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* if the value~0 is the first valid character code. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_First_Char( FT_Face face, @@ -2969,7 +3096,7 @@ FT_BEGIN_HEADER /* char_code :: The starting character code. */ /* */ /* */ - /* agindex :: Glyph index of first character code. 0 if charmap */ + /* agindex :: Glyph index of next character code. 0~if charmap */ /* is empty. */ /* */ /* */ @@ -2980,7 +3107,7 @@ FT_BEGIN_HEADER /* over all character codes available in a given charmap. See the */ /* note for this function for a simple code example. */ /* */ - /* Note that `*agindex' is set to 0 when there are no more codes in */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ /* the charmap. */ /* */ FT_EXPORT( FT_ULong ) @@ -3004,7 +3131,7 @@ FT_BEGIN_HEADER /* glyph_name :: The glyph name. */ /* */ /* */ - /* The glyph index. 0 means `undefined character code'. */ + /* The glyph index. 0~means `undefined character code'. */ /* */ FT_EXPORT( FT_UInt ) FT_Get_Name_Index( FT_Face face, @@ -3046,15 +3173,16 @@ FT_BEGIN_HEADER * * @description: * Retrieve a description of a given subglyph. Only use it if - * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE, or an error is - * returned. + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is + * returned otherwise. * * @input: * glyph :: * The source glyph slot. * * sub_index :: - * The index of subglyph. Must be less than `glyph->num_subglyphs'. + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs'. * * @output: * p_index :: @@ -3073,7 +3201,7 @@ FT_BEGIN_HEADER * The subglyph transformation (if any). * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be @@ -3091,6 +3219,305 @@ FT_BEGIN_HEADER FT_Matrix *p_transform ); + /*************************************************************************/ + /* */ + /* */ + /* FT_FSTYPE_XXX */ + /* */ + /* */ + /* A list of bit flags used in the `fsType' field of the OS/2 table */ + /* in a TrueType or OpenType font and the `FSType' entry in a */ + /* PostScript font. These bit flags are returned by */ + /* @FT_Get_FSType_Flags; they inform client applications of embedding */ + /* and subsetting restrictions associated with a font. */ + /* */ + /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ + /* more details. */ + /* */ + /* */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ + /* Fonts with no fsType bit set may be embedded and permanently */ + /* installed on the remote system by an application. */ + /* */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ + /* Fonts that have only this bit set must not be modified, embedded */ + /* or exchanged in any manner without first obtaining permission of */ + /* the font software copyright owner. */ + /* */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ + /* If this bit is set, the font may be embedded and temporarily */ + /* loaded on the remote system. Documents containing Preview & */ + /* Print fonts must be opened `read-only'; no edits can be applied */ + /* to the document. */ + /* */ + /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ + /* If this bit is set, the font may be embedded but must only be */ + /* installed temporarily on other systems. In contrast to Preview */ + /* & Print fonts, documents containing editable fonts may be opened */ + /* for reading, editing is permitted, and changes may be saved. */ + /* */ + /* FT_FSTYPE_NO_SUBSETTING :: */ + /* If this bit is set, the font may not be subsetted prior to */ + /* embedding. */ + /* */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ + /* If this bit is set, only bitmaps contained in the font may be */ + /* embedded; no outline data may be embedded. If there are no */ + /* bitmaps available in the font, then the font is unembeddable. */ + /* */ + /* */ + /* While the fsType flags can indicate that a font may be embedded, a */ + /* license with the font vendor may be separately required to use the */ + /* font in this way. */ + /* */ +#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 +#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 +#define FT_FSTYPE_NO_SUBSETTING 0x0100 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_FSType_Flags */ + /* */ + /* */ + /* Return the fsType flags for a font. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* */ + /* The fsType flags, @FT_FSTYPE_XXX. */ + /* */ + /* */ + /* Use this function rather than directly reading the `fs_type' field */ + /* in the @PS_FontInfoRec structure which is only guaranteed to */ + /* return the correct results for Type~1 fonts. */ + /* */ + FT_EXPORT( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ); + + + /*************************************************************************/ + /* */ + /*
*/ + /* glyph_variants */ + /* */ + /* */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Report #37, the Ideographic Variation */ + /* Database. To date (October 2007), the character with the most */ + /* variants is U+908A, having 8~such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points which are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points which are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + /*************************************************************************/ /* */ /* <Section> */ @@ -3149,6 +3576,12 @@ FT_BEGIN_HEADER FT_Long c ); + /* */ + + /* The following #if 0 ... #endif is for the documentation formatter, */ + /* hiding the internal `FT_MULFIX_INLINED' macro. */ + +#if 0 /*************************************************************************/ /* */ /* <Function> */ @@ -3182,6 +3615,17 @@ FT_BEGIN_HEADER FT_MulFix( FT_Long a, FT_Long b ); + /* */ +#endif + +#ifdef FT_MULFIX_INLINED +#define FT_MulFix( a, b ) FT_MULFIX_INLINED( a, b ) +#else + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); +#endif + /*************************************************************************/ /* */ @@ -3202,8 +3646,8 @@ FT_BEGIN_HEADER /* The result of `(a*0x10000)/b'. */ /* */ /* <Note> */ - /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ - /* 32 bits, then the division is computed directly. Otherwise, we */ + /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ + /* 32~bits, then the division is computed directly. Otherwise, we */ /* use a specialized version of @FT_MulDiv. */ /* */ FT_EXPORT( FT_Long ) @@ -3310,26 +3754,27 @@ FT_BEGIN_HEADER /************************************************************************* * - * @enum: - * FREETYPE_XXX + * @enum: + * FREETYPE_XXX * - * @description: - * These three macros identify the FreeType source code version. - * Use @FT_Library_Version to access them at runtime. + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. * - * @values: - * FREETYPE_MAJOR :: The major version number. - * FREETYPE_MINOR :: The minor version number. - * FREETYPE_PATCH :: The patch level. + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. * - * @note: - * The version number of FreeType if built as a dynamic link library - * with the `libtool' package is _not_ controlled by these three - * macros. */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 3 -#define FREETYPE_PATCH 5 +#define FREETYPE_PATCH 12 /*************************************************************************/ @@ -3386,8 +3831,8 @@ FT_BEGIN_HEADER /* face :: A face handle. */ /* */ /* <Return> */ - /* 1 if this is a TrueType font that uses one of the patented */ - /* opcodes, 0 otherwise. */ + /* 1~if this is a TrueType font that uses one of the patented */ + /* opcodes, 0~otherwise. */ /* */ /* <Since> */ /* 2.3.5 */ @@ -3413,7 +3858,7 @@ FT_BEGIN_HEADER /* */ /* <Return> */ /* The old setting value. This will always be false if this is not */ - /* a SFNT font, or if the unpatented hinter is not compiled in this */ + /* an SFNT font, or if the unpatented hinter is not compiled in this */ /* instance of the library. */ /* */ /* <Since> */ diff --git a/lib/3rdparty/freetype/include/freetype/ftadvanc.h b/lib/3rdparty/freetype/include/freetype/ftadvanc.h new file mode 100644 index 00000000000..b2451bec426 --- /dev/null +++ b/lib/3rdparty/freetype/include/freetype/ftadvanc.h @@ -0,0 +1,179 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.h */ +/* */ +/* Quick computation of advance widths (specification only). */ +/* */ +/* Copyright 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTADVANC_H__ +#define __FTADVANC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * quick_advance + * + * @title: + * Quick retrieval of advance values + * + * @abstract: + * Retrieve horizontal and vertical advance values without processing + * glyph outlines, if possible. + * + * @description: + * This section contains functions to quickly extract advance values + * without handling glyph outlines, if possible. + */ + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_ADVANCE_FLAG_FAST_ONLY */ + /* */ + /* <Description> */ + /* A bit-flag to be OR-ed with the `flags' parameter of the */ + /* @FT_Get_Advance and @FT_Get_Advances functions. */ + /* */ + /* If set, it indicates that you want these functions to fail if the */ + /* corresponding hinting mode or font driver doesn't allow for very */ + /* quick advance computation. */ + /* */ + /* Typically, glyphs which are either unscaled, unhinted, bitmapped, */ + /* or light-hinted can have their advance width computed very */ + /* quickly. */ + /* */ + /* Normal and bytecode hinted modes, which require loading, scaling, */ + /* and hinting of the glyph outline, are extremely slow by */ + /* comparison. */ + /* */ +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advance */ + /* */ + /* <Description> */ + /* Retrieve the advance value of a given glyph outline in an */ + /* @FT_Face. By default, the unhinted advance is returned in font */ + /* units. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph, used to determine what kind */ + /* of advances you need. */ + /* <Output> */ + /* padvance :: The advance value, in either font units or 16.16 */ + /* format. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ + /* vertical advance corresponding to a vertical layout. */ + /* Otherwise, it is the horizontal advance in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* A scaled advance is returned in 16.16 format but isn't transformed */ + /* by the affine transformation specified by @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags, + FT_Fixed *padvance ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advances */ + /* */ + /* <Description> */ + /* Retrieve the advance values of several glyph outlines in an */ + /* @FT_Face. By default, the unhinted advances are returned in font */ + /* units. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* start :: The first glyph index. */ + /* */ + /* count :: The number of advance values you want to retrieve. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph. */ + /* */ + /* <Output> */ + /* padvance :: The advances, in either font units or 16.16 format. */ + /* This array must contain at least `count' elements. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ + /* vertical advances corresponding to a vertical layout. */ + /* Otherwise, they are the horizontal advances in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* Scaled advances are returned in 16.16 format but aren't */ + /* transformed by the affine transformation specified by */ + /* @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed *padvances ); + +/* */ + + +FT_END_HEADER + +#endif /* __FTADVANC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/include/freetype/ftbbox.h b/lib/3rdparty/freetype/include/freetype/ftbbox.h index 5f79c327405..01fe3fb0d10 100644 --- a/lib/3rdparty/freetype/include/freetype/ftbbox.h +++ b/lib/3rdparty/freetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ /* */ /* FreeType exact bbox computation (specification). */ /* */ -/* Copyright 1996-2001, 2003 by */ +/* Copyright 1996-2001, 2003, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,10 +58,10 @@ FT_BEGIN_HEADER /* FT_Outline_Get_BBox */ /* */ /* <Description> */ - /* Computes the exact bounding box of an outline. This is slower */ + /* Compute the exact bounding box of an outline. This is slower */ /* than computing the control box. However, it uses an advanced */ /* algorithm which returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline BĂ©zier arcs are walked over to */ + /* coincide. Otherwise, the outline BĂ©zier arcs are traversed to */ /* extract their extrema. */ /* */ /* <Input> */ @@ -71,7 +71,7 @@ FT_BEGIN_HEADER /* abbox :: The outline's exact bounding box. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, diff --git a/lib/3rdparty/freetype/include/freetype/ftbdf.h b/lib/3rdparty/freetype/include/freetype/ftbdf.h index 9555694811e..4f8baf84017 100644 --- a/lib/3rdparty/freetype/include/freetype/ftbdf.h +++ b/lib/3rdparty/freetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,38 +38,39 @@ FT_BEGIN_HEADER /* bdf_fonts */ /* */ /* <Title> */ - /* BDF Files */ + /* BDF and PCF Files */ /* */ /* <Abstract> */ - /* BDF specific API. */ + /* BDF and PCF specific API. */ /* */ /* <Description> */ - /* This section contains the declaration of BDF specific functions. */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ /* */ /*************************************************************************/ - /********************************************************************** - * - * @enum: - * FT_PropertyType - * - * @description: - * A list of BDF property types. - * - * @values: - * BDF_PROPERTY_TYPE_NONE :: - * Value 0 is used to indicate a missing property. - * - * BDF_PROPERTY_TYPE_ATOM :: - * Property is a string atom. - * - * BDF_PROPERTY_TYPE_INTEGER :: - * Property is a 32-bit signed integer. - * - * BDF_PROPERTY_TYPE_CARDINAL :: - * Property is a 32-bit unsigned integer. - */ + /********************************************************************** + * + * @enum: + * FT_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ typedef enum BDF_PropertyType_ { BDF_PROPERTY_TYPE_NONE = 0, @@ -80,15 +81,15 @@ FT_BEGIN_HEADER } BDF_PropertyType; - /********************************************************************** - * - * @type: - * BDF_Property - * - * @description: - * A handle to a @BDF_PropertyRec structure to model a given - * BDF/PCF property. - */ + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ typedef struct BDF_PropertyRec_* BDF_Property; @@ -132,7 +133,7 @@ FT_BEGIN_HEADER * FT_Get_BDF_Charset_ID * * @description: - * Retrieves a BDF font character set identity, according to + * Retrieve a BDF font character set identity, according to * the BDF specification. * * @input: @@ -141,13 +142,13 @@ FT_BEGIN_HEADER * * @output: * acharset_encoding :: - * Charset encoding, as a C string, owned by the face. + * Charset encoding, as a C~string, owned by the face. * * acharset_registry :: - * Charset registry, as a C string, owned by the face. + * Charset registry, as a C~string, owned by the face. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function only works with BDF faces, returning an error otherwise. @@ -164,7 +165,7 @@ FT_BEGIN_HEADER * FT_Get_BDF_Property * * @description: - * Retrieves a BDF property from a BDF or PCF font file. + * Retrieve a BDF property from a BDF or PCF font file. * * @input: * face :: A handle to the input face. @@ -175,13 +176,21 @@ FT_BEGIN_HEADER * aproperty :: The property. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function works with BDF _and_ PCF fonts. It returns an error * otherwise. It also returns an error if the property is not in the * font. * + * A `property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props' array within a `FontRec' structure of a PCF font. + * + * Integer properties are always stored as `signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * * In case of error, `aproperty->type' is always set to * @BDF_PROPERTY_TYPE_NONE. */ diff --git a/lib/3rdparty/freetype/include/freetype/ftbitmap.h b/lib/3rdparty/freetype/include/freetype/ftbitmap.h index 337d888eaf2..92742369baa 100644 --- a/lib/3rdparty/freetype/include/freetype/ftbitmap.h +++ b/lib/3rdparty/freetype/include/freetype/ftbitmap.h @@ -2,10 +2,9 @@ /* */ /* ftbitmap.h */ /* */ -/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ -/* bitmaps into 8bpp format (specification). */ +/* FreeType utility functions for bitmaps (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -72,7 +71,7 @@ FT_BEGIN_HEADER /* FT_Bitmap_Copy */ /* */ /* <Description> */ - /* Copies an bitmap into another one. */ + /* Copy a bitmap into another one. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ @@ -83,7 +82,7 @@ FT_BEGIN_HEADER /* target :: A handle to the target bitmap. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Copy( FT_Library library, @@ -114,14 +113,14 @@ FT_BEGIN_HEADER /* bitmap :: A handle to the target bitmap. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The current implementation restricts `xStrength' to be less than */ - /* or equal to 8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ /* */ /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ - /* you should call `FT_GlyphSlot_Own_Bitmap' on the slot first. */ + /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Embolden( FT_Library library, @@ -152,7 +151,7 @@ FT_BEGIN_HEADER /* target :: The target bitmap. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* It is possible to call @FT_Bitmap_Convert multiple times without */ @@ -170,6 +169,28 @@ FT_BEGIN_HEADER FT_Int alignment ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GlyphSlot_Own_Bitmap */ + /* */ + /* <Description> */ + /* Make sure that a glyph slot owns `slot->bitmap'. */ + /* */ + /* <Input> */ + /* slot :: The glyph slot. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function is to be used in combination with */ + /* @FT_Bitmap_Embolden. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + /*************************************************************************/ /* */ /* <Function> */ @@ -184,7 +205,7 @@ FT_BEGIN_HEADER /* bitmap :: The bitmap object to be freed. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `library' argument is taken to have access to FreeType's */ diff --git a/lib/3rdparty/freetype/include/freetype/ftcache.h b/lib/3rdparty/freetype/include/freetype/ftcache.h index 721aa16f32b..0916d70a37e 100644 --- a/lib/3rdparty/freetype/include/freetype/ftcache.h +++ b/lib/3rdparty/freetype/include/freetype/ftcache.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache subsystem (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,10 +36,10 @@ FT_BEGIN_HEADER * Cache Sub-System * * <Abstract> - * How to cache face, size, and glyph data with FreeType 2. + * How to cache face, size, and glyph data with FreeType~2. * * <Description> - * This section describes the FreeType 2 cache sub-system, which is used + * This section describes the FreeType~2 cache sub-system, which is used * to limit the number of concurrently opened @FT_Face and @FT_Size * objects, as well as caching information like character maps and glyph * images while limiting their maximum memory usage. @@ -165,7 +165,7 @@ FT_BEGIN_HEADER * Failure to do so will result in incorrect behaviour or even * memory leaks and crashes. */ - typedef struct FTC_FaceIDRec_* FTC_FaceID; + typedef FT_Pointer FTC_FaceID; /************************************************************************ @@ -193,7 +193,7 @@ FT_BEGIN_HEADER * A new @FT_Face handle. * * <Return> - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * <Note> * The third parameter `req_data' is the same as the one passed by the @@ -260,7 +260,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* An opaque handle to a cache node object. Each cache node is */ - /* reference-counted. A node with a count of 0 might be flushed */ + /* reference-counted. A node with a count of~0 might be flushed */ /* out of a full cache whenever a lookup request is performed. */ /* */ /* If you lookup nodes, you have the ability to `acquire' them, i.e., */ @@ -279,19 +279,19 @@ FT_BEGIN_HEADER /* FTC_Manager_New */ /* */ /* <Description> */ - /* Creates a new cache manager. */ + /* Create a new cache manager. */ /* */ /* <Input> */ /* library :: The parent FreeType library handle to use. */ /* */ /* max_faces :: Maximum number of opened @FT_Face objects managed by */ - /* this cache instance. Use 0 for defaults. */ + /* this cache instance. Use~0 for defaults. */ /* */ /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ - /* this cache instance. Use 0 for defaults. */ + /* this cache instance. Use~0 for defaults. */ /* */ /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ - /* Use 0 for defaults. Note that this value does not */ + /* Use~0 for defaults. Note that this value does not */ /* account for managed @FT_Face and @FT_Size objects. */ /* */ /* requester :: An application-provided callback used to translate */ @@ -301,11 +301,11 @@ FT_BEGIN_HEADER /* each time it is called (see @FTC_Face_Requester). */ /* */ /* <Output> */ - /* amanager :: A handle to a new manager object. 0 in case of */ + /* amanager :: A handle to a new manager object. 0~in case of */ /* failure. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_Manager_New( FT_Library library, @@ -323,7 +323,7 @@ FT_BEGIN_HEADER /* FTC_Manager_Reset */ /* */ /* <Description> */ - /* Empties a given cache manager. This simply gets rid of all the */ + /* Empty a given cache manager. This simply gets rid of all the */ /* currently cached @FT_Face and @FT_Size objects within the manager. */ /* */ /* <InOut> */ @@ -339,7 +339,7 @@ FT_BEGIN_HEADER /* FTC_Manager_Done */ /* */ /* <Description> */ - /* Destroys a given manager after emptying it. */ + /* Destroy a given manager after emptying it. */ /* */ /* <Input> */ /* manager :: A handle to the target cache manager object. */ @@ -354,7 +354,7 @@ FT_BEGIN_HEADER /* FTC_Manager_LookupFace */ /* */ /* <Description> */ - /* Retrieves the @FT_Face object that corresponds to a given face ID */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ /* through a cache manager. */ /* */ /* <Input> */ @@ -366,7 +366,7 @@ FT_BEGIN_HEADER /* aface :: A handle to the face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned @FT_Face object is always owned by the manager. You */ @@ -415,10 +415,10 @@ FT_BEGIN_HEADER /* interpreted as integer pixel character sizes. */ /* Otherwise, they are expressed as 1/64th of points. */ /* */ - /* x_res :: Only used when `pixel' is value 0 to indicate the */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ /* horizontal resolution in dpi. */ /* */ - /* y_res :: Only used when `pixel' is value 0 to indicate the */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ /* vertical resolution in dpi. */ /* */ /* <Note> */ @@ -434,7 +434,18 @@ FT_BEGIN_HEADER FT_UInt x_res; FT_UInt y_res; - } FTC_ScalerRec, *FTC_Scaler; + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; /*************************************************************************/ @@ -455,7 +466,7 @@ FT_BEGIN_HEADER /* asize :: A handle to the size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned @FT_Size object is always owned by the manager. You */ @@ -569,7 +580,7 @@ FT_BEGIN_HEADER * A new cache handle. NULL in case of error. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * Like all other caches, this one will be destroyed with the cache @@ -598,13 +609,14 @@ FT_BEGIN_HEADER * The source face ID. * * cmap_index :: - * The index of the charmap in the source face. + * The index of the charmap in the source face. Any negative value + * means to use the cache @FT_Face's default charmap. * * char_code :: * The character code (in the corresponding charmap). * * @return: - * Glyph index. 0 means `no glyph'. + * Glyph index. 0~means `no glyph'. * */ FT_EXPORT( FT_UInt ) @@ -710,7 +722,7 @@ FT_BEGIN_HEADER /* FTC_ImageCache_New */ /* */ /* <Description> */ - /* Creates a new glyph image cache. */ + /* Create a new glyph image cache. */ /* */ /* <Input> */ /* manager :: The parent manager for the image cache. */ @@ -719,7 +731,7 @@ FT_BEGIN_HEADER /* acache :: A handle to the new glyph image cache object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_New( FTC_Manager manager, @@ -732,7 +744,7 @@ FT_BEGIN_HEADER /* FTC_ImageCache_Lookup */ /* */ /* <Description> */ - /* Retrieves a given glyph image from a glyph image cache. */ + /* Retrieve a given glyph image from a glyph image cache. */ /* */ /* <Input> */ /* cache :: A handle to the source glyph image cache. */ @@ -742,7 +754,7 @@ FT_BEGIN_HEADER /* gindex :: The glyph index to retrieve. */ /* */ /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ /* anode :: Used to return the address of of the corresponding cache */ @@ -750,7 +762,7 @@ FT_BEGIN_HEADER /* below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned glyph is owned and managed by the glyph image cache. */ @@ -795,7 +807,7 @@ FT_BEGIN_HEADER /* gindex :: The glyph index to retrieve. */ /* */ /* <Output> */ - /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ /* anode :: Used to return the address of of the corresponding */ @@ -803,7 +815,7 @@ FT_BEGIN_HEADER /* (see note below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned glyph is owned and managed by the glyph image cache. */ @@ -821,6 +833,9 @@ FT_BEGIN_HEADER /* call to one of the caching sub-system APIs. Don't assume that it */ /* is persistent! */ /* */ + /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ + /* glyphs; you should always use the FreeType cache API instead. */ + /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_LookupScaler( FTC_ImageCache cache, FTC_Scaler scaler, @@ -862,11 +877,11 @@ FT_BEGIN_HEADER /* top :: The vertical distance from the pen position (on the */ /* baseline) to the upper bitmap border (a.k.a. `top */ /* side bearing'). The distance is positive for upwards */ - /* Y coordinates. */ + /* y~coordinates. */ /* */ /* format :: The format of the glyph bitmap (monochrome or gray). */ /* */ - /* max_grays :: Maximum gray level value (in the range 1 to 255). */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ /* */ /* pitch :: The number of bytes per bitmap line. May be positive */ /* or negative. */ @@ -915,7 +930,7 @@ FT_BEGIN_HEADER /* FTC_SBitCache_New */ /* */ /* <Description> */ - /* Creates a new cache to store small glyph bitmaps. */ + /* Create a new cache to store small glyph bitmaps. */ /* */ /* <Input> */ /* manager :: A handle to the source cache manager. */ @@ -924,7 +939,7 @@ FT_BEGIN_HEADER /* acache :: A handle to the new sbit cache. NULL in case of error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_SBitCache_New( FTC_Manager manager, @@ -937,7 +952,7 @@ FT_BEGIN_HEADER /* FTC_SBitCache_Lookup */ /* */ /* <Description> */ - /* Looks up a given small glyph bitmap in a given sbit cache and */ + /* Look up a given small glyph bitmap in a given sbit cache and */ /* `lock' it to prevent its flushing from the cache until needed. */ /* */ /* <Input> */ @@ -955,7 +970,7 @@ FT_BEGIN_HEADER /* below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The small bitmap descriptor and its bit buffer are owned by the */ @@ -963,7 +978,7 @@ FT_BEGIN_HEADER /* as well disappear from memory on the next cache lookup, so don't */ /* treat them as persistent data. */ /* */ - /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ /* glyph bitmap. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ @@ -1010,7 +1025,7 @@ FT_BEGIN_HEADER /* (see note below). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The small bitmap descriptor and its bit buffer are owned by the */ @@ -1018,7 +1033,7 @@ FT_BEGIN_HEADER /* as well disappear from memory on the next cache lookup, so don't */ /* treat them as persistent data. */ /* */ - /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ /* glyph bitmap. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ diff --git a/lib/3rdparty/freetype/include/freetype/ftchapters.h b/lib/3rdparty/freetype/include/freetype/ftchapters.h index bd812c8e65e..7775a6bb00a 100644 --- a/lib/3rdparty/freetype/include/freetype/ftchapters.h +++ b/lib/3rdparty/freetype/include/freetype/ftchapters.h @@ -32,6 +32,7 @@ /* version */ /* basic_types */ /* base_interface */ +/* glyph_variants */ /* glyph_management */ /* mac_specific */ /* sizes_management */ @@ -54,6 +55,7 @@ /* type1_tables */ /* sfnt_names */ /* bdf_fonts */ +/* cid_fonts */ /* pfr_fonts */ /* winfnt_fonts */ /* font_formats */ @@ -88,6 +90,7 @@ /* computations */ /* list_processing */ /* outline_processing */ +/* quick_advance */ /* bitmap_handling */ /* raster */ /* glyph_stroker */ diff --git a/lib/3rdparty/freetype/include/freetype/ftcid.h b/lib/3rdparty/freetype/include/freetype/ftcid.h new file mode 100644 index 00000000000..203a30caf85 --- /dev/null +++ b/lib/3rdparty/freetype/include/freetype/ftcid.h @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCID_H__ +#define __FTCID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * constrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SNFT wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an @FT_Bool. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an @FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + /* */ + +FT_END_HEADER + +#endif /* __FTCID_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/include/freetype/ftgasp.h b/lib/3rdparty/freetype/include/freetype/ftgasp.h index 97cd3301457..91a769e520f 100644 --- a/lib/3rdparty/freetype/include/freetype/ftgasp.h +++ b/lib/3rdparty/freetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (specification). */ /* */ -/* Copyright 2007 by */ +/* Copyright 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,13 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + /*************************************************************************** * * @section: @@ -31,11 +38,11 @@ * Gasp Table * * @abstract: - * Retrieving TrueType `gasp' table entries + * Retrieving TrueType `gasp' table entries. * * @description: * The function @FT_Get_Gasp can be used to query a TrueType or OpenType - * font for specific entries in their `gasp' table, if any. This is + * font for specific entries in its `gasp' table, if any. This is * mainly useful when implementing native TrueType hinting with the * bytecode interpreter to duplicate the Windows text rendering results. */ @@ -95,7 +102,7 @@ * ppem :: The vertical character pixel size. * * @return: - * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE is there is no + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no * `gasp' table in the face. * * @since: diff --git a/lib/3rdparty/freetype/include/freetype/ftglyph.h b/lib/3rdparty/freetype/include/freetype/ftglyph.h index 08058dadd13..0b8f0c04444 100644 --- a/lib/3rdparty/freetype/include/freetype/ftglyph.h +++ b/lib/3rdparty/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -145,7 +145,7 @@ FT_BEGIN_HEADER /* */ /* top :: The top-side bearing, i.e., the vertical distance from */ /* the current pen position to the top border of the glyph */ - /* bitmap. This distance is positive for upwards-y! */ + /* bitmap. This distance is positive for upwards~y! */ /* */ /* bitmap :: A descriptor for the bitmap. */ /* */ @@ -194,7 +194,7 @@ FT_BEGIN_HEADER /* outline :: A descriptor for the outline. */ /* */ /* <Note> */ - /* You can typecast a @FT_Glyph to @FT_OutlineGlyph if you have */ + /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ /* the outline's content easily. */ /* */ @@ -219,7 +219,8 @@ FT_BEGIN_HEADER /* FT_Get_Glyph */ /* */ /* <Description> */ - /* A function used to extract a glyph image from a slot. */ + /* A function used to extract a glyph image from a slot. Note that */ + /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ /* */ /* <Input> */ /* slot :: A handle to the source glyph slot. */ @@ -228,7 +229,7 @@ FT_BEGIN_HEADER /* aglyph :: A handle to the glyph object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, @@ -248,11 +249,11 @@ FT_BEGIN_HEADER /* source :: A handle to the source glyph object. */ /* */ /* <Output> */ - /* target :: A handle to the target glyph object. 0 in case of */ + /* target :: A handle to the target glyph object. 0~in case of */ /* error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_Copy( FT_Glyph source, @@ -265,7 +266,7 @@ FT_BEGIN_HEADER /* FT_Glyph_Transform */ /* */ /* <Description> */ - /* Transforms a glyph image if its format is scalable. */ + /* Transform a glyph image if its format is scalable. */ /* */ /* <InOut> */ /* glyph :: A handle to the target glyph object. */ @@ -375,7 +376,7 @@ FT_BEGIN_HEADER /* expressed in 1/64th of pixels if it is grid-fitted. */ /* */ /* <Note> */ - /* Coordinates are relative to the glyph origin, using the Y-upwards */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ /* convention. */ /* */ /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ @@ -421,17 +422,17 @@ FT_BEGIN_HEADER /* FT_Glyph_To_Bitmap */ /* */ /* <Description> */ - /* Converts a given glyph object to a bitmap glyph object. */ + /* Convert a given glyph object to a bitmap glyph object. */ /* */ /* <InOut> */ /* the_glyph :: A pointer to a handle to the target glyph. */ /* */ /* <Input> */ - /* render_mode :: An enumeration that describe how the data is */ + /* render_mode :: An enumeration that describes how the data is */ /* rendered. */ /* */ /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be 0 (if no */ + /* image before rendering. Can be~0 (if no */ /* translation). The origin is expressed in */ /* 26.6 pixels. */ /* */ @@ -440,15 +441,17 @@ FT_BEGIN_HEADER /* never destroyed in case of error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ /* The glyph image is translated with the `origin' vector before */ /* rendering. */ /* */ /* The first parameter is a pointer to an @FT_Glyph handle, that will */ - /* be replaced by this function. Typically, you would use (omitting */ - /* error handling): */ + /* be _replaced_ by this function (with newly allocated data). */ + /* Typically, you would use (omitting error handling): */ /* */ /* */ /* { */ @@ -462,12 +465,12 @@ FT_BEGIN_HEADER /* // extract glyph image */ /* error = FT_Get_Glyph( face->glyph, &glyph ); */ /* */ - /* // convert to a bitmap (default render mode + destroy old) */ + /* // convert to a bitmap (default render mode + destroying old) */ /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ /* 0, 1 ); */ - /* if ( error ) // glyph unchanged */ + /* if ( error ) // `glyph' unchanged */ /* ... */ /* } */ /* */ @@ -482,7 +485,42 @@ FT_BEGIN_HEADER /* } */ /* */ /* */ - /* This function does nothing if the glyph format isn't scalable. */ + /* Here another example, again without error handling: */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyphs[MAX_GLYPHS] */ + /* */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ + /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* { */ + /* FT_Glyph bitmap = glyphs[idx]; */ + /* */ + /* */ + /* ... */ + /* */ + /* // after this call, `bitmap' no longer points into */ + /* // the `glyphs' array (and the old value isn't destroyed) */ + /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ + /* */ + /* ... */ + /* */ + /* FT_Done_Glyph( bitmap ); */ + /* } */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* FT_Done_Glyph( glyphs[idx] ); */ + /* } */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, @@ -497,7 +535,7 @@ FT_BEGIN_HEADER /* FT_Done_Glyph */ /* */ /* <Description> */ - /* Destroys a given glyph. */ + /* Destroy a given glyph. */ /* */ /* <Input> */ /* glyph :: A handle to the target glyph object. */ @@ -524,7 +562,7 @@ FT_BEGIN_HEADER /* FT_Matrix_Multiply */ /* */ /* <Description> */ - /* Performs the matrix operation `b = a*b'. */ + /* Perform the matrix operation `b = a*b'. */ /* */ /* <Input> */ /* a :: A pointer to matrix `a'. */ @@ -537,7 +575,7 @@ FT_BEGIN_HEADER /* */ FT_EXPORT( void ) FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix* b ); + FT_Matrix* b ); /*************************************************************************/ @@ -546,14 +584,14 @@ FT_BEGIN_HEADER /* FT_Matrix_Invert */ /* */ /* <Description> */ - /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ /* */ /* <InOut> */ /* matrix :: A pointer to the target matrix. Remains untouched in */ /* case of error. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); diff --git a/lib/3rdparty/freetype/include/freetype/ftgxval.h b/lib/3rdparty/freetype/include/freetype/ftgxval.h index c7ea861a0da..497015c1011 100644 --- a/lib/3rdparty/freetype/include/freetype/ftgxval.h +++ b/lib/3rdparty/freetype/include/freetype/ftgxval.h @@ -202,7 +202,7 @@ FT_BEGIN_HEADER * The array itself must be allocated by a client. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function only works with TrueTypeGX fonts, returning an error @@ -285,14 +285,14 @@ FT_BEGIN_HEADER * FT_ClassicKern_Validate * * @description: - * Validate classic (16bit format) kern table to assure that the offsets + * Validate classic (16-bit format) kern table to assure that the offsets * and indices are valid. The idea is that a higher-level library which * actually does the text layout can access those tables without error * checking (which can be quite time consuming). * * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both - * the new 32bit format and the classic 16bit format, while - * FT_ClassicKern_Validate only supports the classic 16bit format. + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. * * @input: * face :: @@ -307,7 +307,7 @@ FT_BEGIN_HEADER * A pointer to the kern table. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * After use, the application should deallocate the buffers pointed to by diff --git a/lib/3rdparty/freetype/include/freetype/ftgzip.h b/lib/3rdparty/freetype/include/freetype/ftgzip.h index 9893437bfa7..acbc4f0327b 100644 --- a/lib/3rdparty/freetype/include/freetype/ftgzip.h +++ b/lib/3rdparty/freetype/include/freetype/ftgzip.h @@ -66,7 +66,7 @@ FT_BEGIN_HEADER * The source stream. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. diff --git a/lib/3rdparty/freetype/include/freetype/ftimage.h b/lib/3rdparty/freetype/include/freetype/ftimage.h index 1c428f117db..0272e92d2b3 100644 --- a/lib/3rdparty/freetype/include/freetype/ftimage.h +++ b/lib/3rdparty/freetype/include/freetype/ftimage.h @@ -5,7 +5,8 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,7 +29,7 @@ #define __FTIMAGE_H__ -/* _STANDALONE_ is from ftgrays.c */ + /* _STANDALONE_ is from ftgrays.c */ #ifndef _STANDALONE_ #include <ft2build.h> #endif @@ -51,10 +52,9 @@ FT_BEGIN_HEADER /* FT_Pos */ /* */ /* <Description> */ - /* The type FT_Pos is a 32-bit integer used to store vectorial */ - /* coordinates. Depending on the context, these can represent */ - /* distances in integer font units, or 16,16, or 26.6 fixed float */ - /* pixel coordinates. */ + /* The type FT_Pos is used to store vectorial coordinates. Depending */ + /* on the context, these can represent distances in integer font */ + /* units, or 16.16, or 26.6 fixed float pixel coordinates. */ /* */ typedef signed long FT_Pos; @@ -99,6 +99,20 @@ FT_BEGIN_HEADER /* */ /* yMax :: The vertical maximum (top-most). */ /* */ + /* <Note> */ + /* The bounding box is specified with the coordinates of the lower */ + /* left and the upper right corner. In PostScript, those values are */ + /* often called (llx,lly) and (urx,ury), respectively. */ + /* */ + /* If `yMin' is negative, this value gives the glyph's descender. */ + /* Otherwise, the glyph doesn't descend below the baseline. */ + /* Similarly, if `ymax' is positive, this value gives the glyph's */ + /* ascender. */ + /* */ + /* `xMin' gives the horizontal distance from the glyph's origin to */ + /* the left edge of the glyph's bounding box. If `xMin' is negative, */ + /* the glyph extends to the left of the origin. */ + /* */ typedef struct FT_BBox_ { FT_Pos xMin, yMin; @@ -119,39 +133,40 @@ FT_BEGIN_HEADER /* */ /* <Values> */ /* FT_PIXEL_MODE_NONE :: */ - /* Value 0 is reserved. */ + /* Value~0 is reserved. */ /* */ /* FT_PIXEL_MODE_MONO :: */ - /* A monochrome bitmap, using 1 bit per pixel. Note that pixels */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ /* are stored in most-significant order (MSB), which means that */ /* the left-most pixel in a byte has value 128. */ /* */ /* FT_PIXEL_MODE_GRAY :: */ /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ /* images. Each pixel is stored in one byte. Note that the number */ - /* of value `gray' levels is stored in the `num_bytes' field of */ - /* the @FT_Bitmap structure (it generally is 256). */ + /* of `gray' levels is stored in the `num_grays' field of the */ + /* @FT_Bitmap structure (it generally is 256). */ /* */ /* FT_PIXEL_MODE_GRAY2 :: */ - /* A 2-bit/pixel bitmap, used to represent embedded anti-aliased */ - /* bitmaps in font files according to the OpenType specification. */ - /* We haven't found a single font using this format, however. */ + /* A 2-bit per pixel bitmap, used to represent embedded */ + /* anti-aliased bitmaps in font files according to the OpenType */ + /* specification. We haven't found a single font using this */ + /* format, however. */ /* */ /* FT_PIXEL_MODE_GRAY4 :: */ - /* A 4-bit/pixel bitmap, used to represent embedded anti-aliased */ + /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ /* bitmaps in font files according to the OpenType specification. */ /* We haven't found a single font using this format, however. */ /* */ /* FT_PIXEL_MODE_LCD :: */ - /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ - /* images used for display on LCD displays; the bitmap is three */ - /* times wider than the original glyph image. See also */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on LCD displays; the bitmap is three times */ + /* wider than the original glyph image. See also */ /* @FT_RENDER_MODE_LCD. */ /* */ /* FT_PIXEL_MODE_LCD_V :: */ - /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ - /* images used for display on rotated LCD displays; the bitmap */ - /* is three times taller than the original glyph image. See also */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on rotated LCD displays; the bitmap is three */ + /* times taller than the original glyph image. See also */ /* @FT_RENDER_MODE_LCD_V. */ /* */ typedef enum FT_Pixel_Mode_ @@ -206,11 +221,11 @@ FT_BEGIN_HEADER /* An enumeration type to describe the format of a bitmap palette, */ /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ /* */ - /* <Fields> */ - /* ft_palette_mode_rgb :: The palette is an array of 3-bytes RGB */ + /* <Values> */ + /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ /* records. */ /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-bytes RGBA */ + /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ /* records. */ /* */ /* <Note> */ @@ -222,7 +237,7 @@ FT_BEGIN_HEADER ft_palette_mode_rgb = 0, ft_palette_mode_rgba, - ft_palettte_mode_max /* do not remove */ + ft_palette_mode_max /* do not remove */ } FT_Palette_Mode; @@ -253,6 +268,9 @@ FT_BEGIN_HEADER /* flow. In all cases, the pitch is an offset to add */ /* to a bitmap pointer in order to go down one row. */ /* */ + /* For the B/W rasterizer, `pitch' is always an even */ + /* number. */ + /* */ /* buffer :: A typeless pointer to the bitmap buffer. This */ /* value should be aligned on 32-bit boundaries in */ /* most cases. */ @@ -317,14 +335,23 @@ FT_BEGIN_HEADER /* elements, giving the outline's point coordinates. */ /* */ /* tags :: A pointer to an array of `n_points' chars, giving */ - /* each outline point's type. If bit 0 is unset, the */ - /* point is `off' the curve, i.e., a BĂ©zier control */ - /* point, while it is `on' when set. */ + /* each outline point's type. */ /* */ - /* Bit 1 is meaningful for `off' points only. If set, */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a BĂ©zier control point, while it is `on' if */ + /* set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ /* it indicates a third-order BĂ©zier arc control point; */ /* and a second-order control point if unset. */ /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ /* contours :: An array of `n_contours' shorts, giving the end */ /* point of each contour within the outline. For */ /* example, the first contour is defined by the points */ @@ -335,6 +362,12 @@ FT_BEGIN_HEADER /* and give hints to the scan-converter and hinter on */ /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ /* */ + /* <Note> */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ typedef struct FT_Outline_ { short n_contours; /* number of contours in glyph */ @@ -348,71 +381,91 @@ FT_BEGIN_HEADER } FT_Outline; + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + /*************************************************************************/ /* */ /* <Enum> */ - /* FT_OUTLINE_FLAGS */ + /* FT_OUTLINE_FLAGS */ /* */ /* <Description> */ /* A list of bit-field constants use for the flags in an outline's */ /* `flags' field. */ /* */ /* <Values> */ - /* FT_OUTLINE_NONE :: Value 0 is reserved. */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ /* */ - /* FT_OUTLINE_OWNER :: If set, this flag indicates that the */ - /* outline's field arrays (i.e., */ - /* `points', `flags' & `contours') are */ - /* `owned' by the outline object, and */ - /* should thus be freed when it is */ - /* destroyed. */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ /* */ - /* FT_OUTLINE_EVEN_ODD_FILL :: By default, outlines are filled using */ - /* the non-zero winding rule. If set to */ - /* 1, the outline will be filled using */ - /* the even-odd fill rule (only works */ - /* with the smooth raster). */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth rasterizer). */ /* */ - /* FT_OUTLINE_REVERSE_FILL :: By default, outside contours of an */ - /* outline are oriented in clock-wise */ - /* direction, as defined in the TrueType */ - /* specification. This flag is set if */ - /* the outline uses the opposite */ - /* direction (typically for Type 1 */ - /* fonts). This flag is ignored by the */ - /* scan-converter. */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ /* */ - /* FT_OUTLINE_IGNORE_DROPOUTS :: By default, the scan converter will */ - /* try to detect drop-outs in an outline */ - /* and correct the glyph bitmap to */ - /* ensure consistent shape continuity. */ - /* If set, this flag hints the scan-line */ - /* converter to ignore such cases. */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. See below for more information. */ /* */ - /* FT_OUTLINE_HIGH_PRECISION :: This flag indicates that the */ - /* scan-line converter should try to */ - /* convert this outline to bitmaps with */ - /* the highest possible quality. It is */ - /* typically set for small character */ - /* sizes. Note that this is only a */ - /* hint, that might be completely */ - /* ignored by a given scan-converter. */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ /* */ - /* FT_OUTLINE_SINGLE_PASS :: This flag is set to force a given */ - /* scan-converter to only use a single */ - /* pass over the outline to render a */ - /* bitmap glyph image. Normally, it is */ - /* set for very large character sizes. */ - /* It is only a hint, that might be */ - /* completely ignored by a given */ - /* scan-converter. */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ /* */ #define FT_OUTLINE_NONE 0x0 #define FT_OUTLINE_OWNER 0x1 #define FT_OUTLINE_EVEN_ODD_FILL 0x2 #define FT_OUTLINE_REVERSE_FILL 0x4 #define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 #define FT_OUTLINE_HIGH_PRECISION 0x100 #define FT_OUTLINE_SINGLE_PASS 0x200 @@ -448,21 +501,24 @@ FT_BEGIN_HEADER #define FT_CURVE_TAG( flag ) ( flag & 3 ) -#define FT_CURVE_TAG_ON 1 -#define FT_CURVE_TAG_CONIC 0 -#define FT_CURVE_TAG_CUBIC 2 +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 -#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ -#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_HAS_SCANMODE 4 -#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ - FT_CURVE_TAG_TOUCH_Y ) +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y -#define FT_Curve_Tag_On FT_CURVE_TAG_ON -#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC -#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC -#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X -#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y /*************************************************************************/ /* */ @@ -482,7 +538,7 @@ FT_BEGIN_HEADER /* decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_MoveToFunc)( const FT_Vector* to, @@ -490,6 +546,7 @@ FT_BEGIN_HEADER #define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + /*************************************************************************/ /* */ /* <FuncType> */ @@ -508,13 +565,14 @@ FT_BEGIN_HEADER /* decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_LineToFunc)( const FT_Vector* to, void* user ); -#define FT_Outline_LineTo_Func FT_Outline_LineToFunc +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + /*************************************************************************/ /* */ @@ -522,8 +580,8 @@ FT_BEGIN_HEADER /* FT_Outline_ConicToFunc */ /* */ /* <Description> */ - /* A function pointer type use to describe the signature of a `conic */ - /* to' function during outline walking/decomposition. */ + /* A function pointer type used to describe the signature of a `conic */ + /* to' function during outline walking or decomposition. */ /* */ /* A `conic to' is emitted to indicate a second-order BĂ©zier arc in */ /* the outline. */ @@ -538,14 +596,15 @@ FT_BEGIN_HEADER /* the decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_ConicToFunc)( const FT_Vector* control, const FT_Vector* to, void* user ); -#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + /*************************************************************************/ /* */ @@ -554,7 +613,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking/decomposition. */ + /* to' function during outline walking or decomposition. */ /* */ /* A `cubic to' is emitted to indicate a third-order BĂ©zier arc. */ /* */ @@ -569,7 +628,7 @@ FT_BEGIN_HEADER /* the decomposition function. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_CubicToFunc)( const FT_Vector* control1, @@ -577,7 +636,7 @@ FT_BEGIN_HEADER const FT_Vector* to, void* user ); -#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc /*************************************************************************/ @@ -587,8 +646,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic BĂ©ziers, */ - /* as well as `move to' and `close to' operations. */ + /* decomposition in order to emit segments, conic, and cubic BĂ©ziers. */ /* */ /* <Fields> */ /* move_to :: The `move to' emitter. */ @@ -615,7 +673,7 @@ FT_BEGIN_HEADER /* y' = (x << shift) - delta */ /* } */ /* */ - /* Set the value of `shift' and `delta' to 0 to get the original */ + /* Set the values of `shift' and `delta' to~0 to get the original */ /* point coordinates. */ /* */ typedef struct FT_Outline_Funcs_ @@ -648,7 +706,7 @@ FT_BEGIN_HEADER /* This macro converts four-letter tags to an unsigned long type. */ /* */ /* <Note> */ - /* Since many 16bit compilers don't like 32bit enumerations, you */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ /* should redefine this macro in case of problems to something like */ /* this: */ /* */ @@ -680,7 +738,7 @@ FT_BEGIN_HEADER /* */ /* <Values> */ /* FT_GLYPH_FORMAT_NONE :: */ - /* The value 0 is reserved. */ + /* The value~0 is reserved. */ /* */ /* FT_GLYPH_FORMAT_COMPOSITE :: */ /* The glyph image is a composite of several other images. This */ @@ -700,7 +758,7 @@ FT_BEGIN_HEADER /* */ /* FT_GLYPH_FORMAT_PLOTTER :: */ /* The glyph image is a vectorial path with no inside and outside */ - /* contours. Some Type 1 fonts, like those in the Hershey family, */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ /* contain glyphs in this format. These are described as */ /* @FT_Outline, but FreeType isn't currently capable of rendering */ /* them correctly. */ @@ -812,10 +870,11 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* This structure is used by the span drawing callback type named */ - /* @FT_SpanFunc which takes the y-coordinate of the span as a */ + /* @FT_SpanFunc which takes the y~coordinate of the span as a */ /* a parameter. */ /* */ - /* The coverage value is always between 0 and 255. */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ /* */ typedef struct FT_Span_ { @@ -837,7 +896,7 @@ FT_BEGIN_HEADER /* spans on each scan line. */ /* */ /* <Input> */ - /* y :: The scanline's y-coordinate. */ + /* y :: The scanline's y~coordinate. */ /* */ /* count :: The number of spans to draw on this scanline. */ /* */ @@ -854,8 +913,8 @@ FT_BEGIN_HEADER /* */ /* Note that the `count' field cannot be greater than a fixed value */ /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ - /* `ftoption.h'. By default, this value is set to 32, which means */ - /* that if there are more than 32 spans on a given scanline, the */ + /* `ftoption.h'. By default, this value is set to~32, which means */ + /* that if there are more than 32~spans on a given scanline, the */ /* callback is called several times with the same `y' parameter in */ /* order to draw all callbacks. */ /* */ @@ -868,7 +927,7 @@ FT_BEGIN_HEADER const FT_Span* spans, void* user ); -#define FT_Raster_Span_Func FT_SpanFunc +#define FT_Raster_Span_Func FT_SpanFunc /*************************************************************************/ @@ -885,14 +944,14 @@ FT_BEGIN_HEADER /* per-se the TrueType spec. */ /* */ /* <Input> */ - /* y :: The pixel's y-coordinate. */ + /* y :: The pixel's y~coordinate. */ /* */ - /* x :: The pixel's x-coordinate. */ + /* x :: The pixel's x~coordinate. */ /* */ /* user :: User-supplied data that is passed to the callback. */ /* */ /* <Return> */ - /* 1 if the pixel is `set', 0 otherwise. */ + /* 1~if the pixel is `set', 0~otherwise. */ /* */ typedef int (*FT_Raster_BitTest_Func)( int y, @@ -913,14 +972,14 @@ FT_BEGIN_HEADER /* drop-out control according to the TrueType specification. */ /* */ /* <Input> */ - /* y :: The pixel's y-coordinate. */ + /* y :: The pixel's y~coordinate. */ /* */ - /* x :: The pixel's x-coordinate. */ + /* x :: The pixel's x~coordinate. */ /* */ /* user :: User-supplied data that is passed to the callback. */ /* */ /* <Return> */ - /* 1 if the pixel is `set', 0 otherwise. */ + /* 1~if the pixel is `set', 0~otherwise. */ /* */ typedef void (*FT_Raster_BitSet_Func)( int y, @@ -999,7 +1058,7 @@ FT_BEGIN_HEADER /* */ /* gray_spans :: The gray span drawing callback. */ /* */ - /* black_spans :: The black span drawing callback. */ + /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ /* */ /* bit_test :: The bit test callback. UNIMPLEMENTED! */ /* */ @@ -1036,7 +1095,7 @@ FT_BEGIN_HEADER const void* source; int flags; FT_SpanFunc gray_spans; - FT_SpanFunc black_spans; + FT_SpanFunc black_spans; /* doesn't work! */ FT_Raster_BitTest_Func bit_test; /* doesn't work! */ FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; @@ -1060,7 +1119,7 @@ FT_BEGIN_HEADER /* raster :: A handle to the new raster object. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ /* <Note> */ /* The `memory' parameter is a typeless pointer in order to avoid */ @@ -1073,7 +1132,8 @@ FT_BEGIN_HEADER (*FT_Raster_NewFunc)( void* memory, FT_Raster* raster ); -#define FT_Raster_New_Func FT_Raster_NewFunc +#define FT_Raster_New_Func FT_Raster_NewFunc + /*************************************************************************/ /* */ @@ -1089,7 +1149,8 @@ FT_BEGIN_HEADER typedef void (*FT_Raster_DoneFunc)( FT_Raster raster ); -#define FT_Raster_Done_Func FT_Raster_DoneFunc +#define FT_Raster_Done_Func FT_Raster_DoneFunc + /*************************************************************************/ /* */ @@ -1123,7 +1184,8 @@ FT_BEGIN_HEADER unsigned char* pool_base, unsigned long pool_size ); -#define FT_Raster_Reset_Func FT_Raster_ResetFunc +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + /*************************************************************************/ /* */ @@ -1148,7 +1210,8 @@ FT_BEGIN_HEADER unsigned long mode, void* args ); -#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + /*************************************************************************/ /* */ @@ -1156,8 +1219,8 @@ FT_BEGIN_HEADER /* FT_Raster_RenderFunc */ /* */ /* <Description> */ - /* Invokes a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ /* */ /* <Input> */ /* raster :: A handle to the raster object. */ @@ -1166,7 +1229,7 @@ FT_BEGIN_HEADER /* store the rendering parameters. */ /* */ /* <Return> */ - /* Error code. 0 means success. */ + /* Error code. 0~means success. */ /* */ /* <Note> */ /* The exact format of the source image depends on the raster's glyph */ @@ -1188,7 +1251,8 @@ FT_BEGIN_HEADER (*FT_Raster_RenderFunc)( FT_Raster raster, const FT_Raster_Params* params ); -#define FT_Raster_Render_Func FT_Raster_RenderFunc +#define FT_Raster_Render_Func FT_Raster_RenderFunc + /*************************************************************************/ /* */ @@ -1211,12 +1275,12 @@ FT_BEGIN_HEADER /* */ typedef struct FT_Raster_Funcs_ { - FT_Glyph_Format glyph_format; - FT_Raster_NewFunc raster_new; - FT_Raster_ResetFunc raster_reset; - FT_Raster_SetModeFunc raster_set_mode; - FT_Raster_RenderFunc raster_render; - FT_Raster_DoneFunc raster_done; + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; } FT_Raster_Funcs; diff --git a/lib/3rdparty/freetype/include/freetype/ftincrem.h b/lib/3rdparty/freetype/include/freetype/ftincrem.h index 46bc8bdd37c..aaf689ff16c 100644 --- a/lib/3rdparty/freetype/include/freetype/ftincrem.h +++ b/lib/3rdparty/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002, 2003, 2006, 2007 by */ +/* Copyright 2002, 2003, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,192 +31,212 @@ FT_BEGIN_HEADER - /*************************************************************************** - * - * @section: - * incremental - * - * @title: - * Incremental Loading - * - * @abstract: - * Custom Glyph Loading. - * - * @description: - * This section contains various functions used to perform so-called - * `incremental' glyph loading. This is a mode where all glyphs loaded - * from a given @FT_Face are provided by the client application, - * - * Apart from that, all other tables are loaded normally from the font - * file. This mode is useful when FreeType is used within another - * engine, e.g., a Postscript Imaging Processor. - * - * To enable this mode, you must use @FT_Open_Face, passing an - * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an - * @FT_Incremental_Interface value. See the comments for - * @FT_Incremental_InterfaceRec for an example. - * - */ + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application, + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ - /*************************************************************************** - * - * @type: - * FT_Incremental - * - * @description: - * An opaque type describing a user-provided object used to implement - * `incremental' glyph loading within FreeType. This is used to support - * embedded fonts in certain environments (e.g., Postscript interpreters), - * where the glyph data isn't in the font file, or must be overridden by - * different values. - * - * @note: - * It is up to client applications to create and implement @FT_Incremental - * objects, as long as they provide implementations for the methods - * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc - * and @FT_Incremental_GetGlyphMetricsFunc. - * - * See the description of @FT_Incremental_InterfaceRec to understand how - * to use incremental objects with FreeType. - */ + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ typedef struct FT_IncrementalRec_* FT_Incremental; - /*************************************************************************** - * - * @struct: - * FT_Incremental_Metrics - * - * @description: - * A small structure used to contain the basic glyph metrics returned - * by the @FT_Incremental_GetGlyphMetricsFunc method. - * - * @fields: - * bearing_x :: - * Left bearing, in font units. - * - * bearing_y :: - * Top bearing, in font units. - * - * advance :: - * Glyph advance, in font units. - * - * @note: - * These correspond to horizontal or vertical metrics depending on the - * value of the `vertical' argument to the function - * @FT_Incremental_GetGlyphMetricsFunc. - */ + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Horizontal component of glyph advance, in font units. + * + * advance_v :: + * Vertical component of glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ typedef struct FT_Incremental_MetricsRec_ { FT_Long bearing_x; FT_Long bearing_y; FT_Long advance; + FT_Long advance_v; /* since 2.3.12 */ - } FT_Incremental_MetricsRec, *FT_Incremental_Metrics; + } FT_Incremental_MetricsRec; - /*************************************************************************** - * - * @type: - * FT_Incremental_GetGlyphDataFunc - * - * @description: - * A function called by FreeType to access a given glyph's data bytes - * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is - * enabled. - * - * Note that the format of the glyph's data bytes depends on the font - * file format. For TrueType, it must correspond to the raw bytes within - * the `glyf' table. For Postscript formats, it must correspond to the - * *unencrypted* charstring bytes, without any `lenIV' header. It is - * undefined for any other format. - * - * @input: - * incremental :: - * Handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * glyph_index :: - * Index of relevant glyph. - * - * @output: - * adata :: - * A structure describing the returned glyph data bytes (which will be - * accessed as a read-only byte block). - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * If this function returns successfully the method - * @FT_Incremental_FreeGlyphDataFunc will be called later to release - * the data bytes. - * - * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for - * compound glyphs. - */ + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ typedef FT_Error (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, FT_UInt glyph_index, FT_Data* adata ); - /*************************************************************************** - * - * @type: - * FT_Incremental_FreeGlyphDataFunc - * - * @description: - * A function used to release the glyph data bytes returned by a - * successful call to @FT_Incremental_GetGlyphDataFunc. - * - * @input: - * incremental :: - * A handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * data :: - * A structure describing the glyph data bytes (which will be accessed - * as a read-only byte block). - */ + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ typedef void (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, FT_Data* data ); - /*************************************************************************** - * - * @type: - * FT_Incremental_GetGlyphMetricsFunc - * - * @description: - * A function used to retrieve the basic metrics of a given glyph index - * before accessing its data. This is necessary because, in certain - * formats like TrueType, the metrics are stored in a different place from - * the glyph images proper. - * - * @input: - * incremental :: - * A handle to an opaque @FT_Incremental handle provided by the client - * application. - * - * glyph_index :: - * Index of relevant glyph. - * - * vertical :: - * If true, return vertical metrics. - * - * ametrics :: - * This parameter is used for both input and output. - * The original glyph metrics, if any, in font units. If metrics are - * not available all the values must be set to zero. - * - * @output: - * ametrics :: - * The replacement glyph metrics in font units. - * - */ + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ typedef FT_Error (*FT_Incremental_GetGlyphMetricsFunc) ( FT_Incremental incremental, @@ -244,6 +264,7 @@ FT_BEGIN_HEADER * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does * not provide overriding glyph metrics. + * */ typedef struct FT_Incremental_FuncsRec_ { @@ -254,41 +275,42 @@ FT_BEGIN_HEADER } FT_Incremental_FuncsRec; - /*************************************************************************** - * - * @struct: - * FT_Incremental_InterfaceRec - * - * @description: - * A structure to be used with @FT_Open_Face to indicate that the user - * wants to support incremental glyph loading. You should use it with - * @FT_PARAM_TAG_INCREMENTAL as in the following example: - * - * { - * FT_Incremental_InterfaceRec inc_int; - * FT_Parameter parameter; - * FT_Open_Args open_args; - * - * - * // set up incremental descriptor - * inc_int.funcs = my_funcs; - * inc_int.object = my_object; - * - * // set up optional parameter - * parameter.tag = FT_PARAM_TAG_INCREMENTAL; - * parameter.data = &inc_int; - * - * // set up FT_Open_Args structure - * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; - * open_args.pathname = my_font_pathname; - * open_args.num_params = 1; - * open_args.params = ¶meter; // we use one optional argument - * - * // open the font - * error = FT_Open_Face( library, &open_args, index, &face ); - * ... - * } - */ + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ typedef struct FT_Incremental_InterfaceRec_ { const FT_Incremental_FuncsRec* funcs; @@ -297,31 +319,31 @@ FT_BEGIN_HEADER } FT_Incremental_InterfaceRec; - /*************************************************************************** - * - * @type: - * FT_Incremental_Interface - * - * @description: - * A pointer to an @FT_Incremental_InterfaceRec structure. - * - */ + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_INCREMENTAL - * - * @description: - * A constant used as the tag of @FT_Parameter structures to indicate - * an incremental loading object to be used by FreeType. - * - */ + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ #define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) - /* */ + /* */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/ftlcdfil.h b/lib/3rdparty/freetype/include/freetype/ftlcdfil.h index 9a61377a394..c6201b38e99 100644 --- a/lib/3rdparty/freetype/include/freetype/ftlcdfil.h +++ b/lib/3rdparty/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -85,7 +91,7 @@ FT_BEGIN_HEADER * @since: * 2.3.0 */ - typedef enum + typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, @@ -119,7 +125,7 @@ FT_BEGIN_HEADER * well on most LCD screens. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This feature is always disabled by default. Clients must make an @@ -141,8 +147,8 @@ FT_BEGIN_HEADER * If this feature is activated, the dimensions of LCD glyph bitmaps are * either larger or taller than the dimensions of the corresponding * outline with regards to the pixel grid. For example, for - * @FT_RENDER_MODE_LCD, the filter adds up to 3 pixels to the left, and - * up to 3 pixels to the right. + * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and + * up to 3~pixels to the right. * * The bitmap offset values are adjusted correctly, so clients shouldn't * need to modify their layout and glyph positioning code when enabling diff --git a/lib/3rdparty/freetype/include/freetype/ftlist.h b/lib/3rdparty/freetype/include/freetype/ftlist.h index f3223ee8fdb..93b05fc0d62 100644 --- a/lib/3rdparty/freetype/include/freetype/ftlist.h +++ b/lib/3rdparty/freetype/include/freetype/ftlist.h @@ -81,7 +81,7 @@ FT_BEGIN_HEADER /* FT_List_Find */ /* */ /* <Description> */ - /* Finds the list node for a given listed object. */ + /* Find the list node for a given listed object. */ /* */ /* <Input> */ /* list :: A pointer to the parent list. */ @@ -101,7 +101,7 @@ FT_BEGIN_HEADER /* FT_List_Add */ /* */ /* <Description> */ - /* Appends an element to the end of a list. */ + /* Append an element to the end of a list. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ @@ -118,7 +118,7 @@ FT_BEGIN_HEADER /* FT_List_Insert */ /* */ /* <Description> */ - /* Inserts an element at the head of a list. */ + /* Insert an element at the head of a list. */ /* */ /* <InOut> */ /* list :: A pointer to parent list. */ @@ -135,7 +135,7 @@ FT_BEGIN_HEADER /* FT_List_Remove */ /* */ /* <Description> */ - /* Removes a node from a list. This function doesn't check whether */ + /* Remove a node from a list. This function doesn't check whether */ /* the node is in the list! */ /* */ /* <Input> */ @@ -155,7 +155,7 @@ FT_BEGIN_HEADER /* FT_List_Up */ /* */ /* <Description> */ - /* Moves a node to the head/top of a list. Used to maintain LRU */ + /* Move a node to the head/top of a list. Used to maintain LRU */ /* lists. */ /* */ /* <InOut> */ @@ -193,7 +193,7 @@ FT_BEGIN_HEADER /* FT_List_Iterate */ /* */ /* <Description> */ - /* Parses a list and calls a given iterator function on each element. */ + /* Parse a list and calls a given iterator function on each element. */ /* Note that parsing is stopped as soon as one of the iterator calls */ /* returns a non-zero value. */ /* */ @@ -242,7 +242,7 @@ FT_BEGIN_HEADER /* FT_List_Finalize */ /* */ /* <Description> */ - /* Destroys all elements in the list as well as the list itself. */ + /* Destroy all elements in the list as well as the list itself. */ /* */ /* <Input> */ /* list :: A handle to the list. */ diff --git a/lib/3rdparty/freetype/include/freetype/ftlzw.h b/lib/3rdparty/freetype/include/freetype/ftlzw.h index d950653ebf8..00d40169a75 100644 --- a/lib/3rdparty/freetype/include/freetype/ftlzw.h +++ b/lib/3rdparty/freetype/include/freetype/ftlzw.h @@ -63,7 +63,7 @@ FT_BEGIN_HEADER * source :: The source stream. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. diff --git a/lib/3rdparty/freetype/include/freetype/ftmac.h b/lib/3rdparty/freetype/include/freetype/ftmac.h index 3c6fafe5500..ab5bab5170c 100644 --- a/lib/3rdparty/freetype/include/freetype/ftmac.h +++ b/lib/3rdparty/freetype/include/freetype/ftmac.h @@ -18,9 +18,9 @@ /***************************************************************************/ /* */ -/* NOTE: Include this file after <freetype/freetype.h> and after the */ -/* Mac-specific <Types.h> header (or any other Mac header that */ -/* includes <Types.h>); we use Handle type. */ +/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ /* */ /***************************************************************************/ @@ -85,7 +85,7 @@ FT_BEGIN_HEADER /* aface :: A handle to a new face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Notes> */ /* This function can be used to create @FT_Face objects from fonts */ @@ -100,7 +100,8 @@ FT_BEGIN_HEADER FT_New_Face_From_FOND( FT_Library library, Handle fond, FT_Long face_index, - FT_Face *aface ); + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ @@ -123,7 +124,7 @@ FT_BEGIN_HEADER /* @FT_New_Face_From_FSSpec. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, @@ -151,7 +152,7 @@ FT_BEGIN_HEADER /* @FT_New_Face_From_FSSpec. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, @@ -182,13 +183,14 @@ FT_BEGIN_HEADER /* face_index :: Index of the face. For passing to @FT_New_Face. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, UInt8* path, UInt32 maxPathSize, - FT_Long* face_index ); + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ @@ -207,12 +209,12 @@ FT_BEGIN_HEADER /* spec :: FSSpec to the font file. */ /* */ /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ + /* first face has index~0. */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ @@ -242,12 +244,12 @@ FT_BEGIN_HEADER /* spec :: FSRef to the font file. */ /* */ /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ + /* first face has index~0. */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ diff --git a/lib/3rdparty/freetype/include/freetype/ftmm.h b/lib/3rdparty/freetype/include/freetype/ftmm.h index a9ccfe71380..3aefb9e4f25 100644 --- a/lib/3rdparty/freetype/include/freetype/ftmm.h +++ b/lib/3rdparty/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -44,7 +44,7 @@ FT_BEGIN_HEADER /* setting design axis coordinates. */ /* */ /* George Williams has extended this interface to make it work with */ - /* both Type 1 Multiple Masters fonts and GX distortable (var) */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ /* fonts. Some of these routines only work with MM fonts, others */ /* will work with both types. They are similar enough that a */ /* consistent interface makes sense. */ @@ -91,12 +91,12 @@ FT_BEGIN_HEADER /* This structure can't be used for GX var fonts. */ /* */ /* <Fields> */ - /* num_axis :: Number of axes. Cannot exceed 4. */ + /* num_axis :: Number of axes. Cannot exceed~4. */ /* */ /* num_designs :: Number of designs; should be normally 2^num_axis */ - /* even though the Type 1 specification strangely */ + /* even though the Type~1 specification strangely */ /* allows for intermediate designs to be present. This */ - /* number cannot exceed 16. */ + /* number cannot exceed~16. */ /* */ /* axis :: A table of axis descriptors. */ /* */ @@ -187,7 +187,7 @@ FT_BEGIN_HEADER /* Some fields are specific to one format and not to the other. */ /* */ /* <Fields> */ - /* num_axis :: The number of axes. The maximum value is 4 for */ + /* num_axis :: The number of axes. The maximum value is~4 for */ /* MM; no limit in GX. */ /* */ /* num_designs :: The number of designs; should be normally */ @@ -227,7 +227,7 @@ FT_BEGIN_HEADER /* FT_Get_Multi_Master */ /* */ /* <Description> */ - /* Retrieves the Multiple Master descriptor of a given font. */ + /* Retrieve the Multiple Master descriptor of a given font. */ /* */ /* This function can't be used with GX fonts. */ /* */ @@ -238,7 +238,7 @@ FT_BEGIN_HEADER /* amaster :: The Multiple Masters descriptor. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Multi_Master( FT_Face face, @@ -251,18 +251,18 @@ FT_BEGIN_HEADER /* FT_Get_MM_Var */ /* */ /* <Description> */ - /* Retrieves the Multiple Master/GX var descriptor of a given font. */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Output> */ - /* amaster :: The Multiple Masters descriptor. */ + /* amaster :: The Multiple Masters/GX var descriptor. */ /* Allocates a data structure, which the user must free */ /* (a single call to FT_FREE will do it). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_MM_Var( FT_Face face, @@ -290,7 +290,7 @@ FT_BEGIN_HEADER /* coords :: An array of design coordinates. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, @@ -317,7 +317,7 @@ FT_BEGIN_HEADER /* coords :: An array of design coordinates. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, @@ -345,7 +345,7 @@ FT_BEGIN_HEADER /* between 0 and 1.0). */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, diff --git a/lib/3rdparty/freetype/include/freetype/ftmodapi.h b/lib/3rdparty/freetype/include/freetype/ftmodapi.h index 9cc32aff4e1..3c9b876dfee 100644 --- a/lib/3rdparty/freetype/include/freetype/ftmodapi.h +++ b/lib/3rdparty/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -78,12 +78,50 @@ FT_BEGIN_HEADER typedef FT_Pointer FT_Module_Interface; + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ typedef void (*FT_Module_Destructor)( FT_Module module ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, const char* name ); @@ -112,14 +150,11 @@ FT_BEGIN_HEADER /* as a 16.16 fixed number (major.minor). Starts */ /* at version 2.0, i.e., 0x20000. */ /* */ - /* module_init :: A function used to initialize (not create) a */ - /* new module object. */ + /* module_init :: The initializing function. */ /* */ - /* module_done :: A function used to finalize (not destroy) a */ - /* given module object */ + /* module_done :: The finalizing function. */ /* */ - /* get_interface :: Queries a given module for a specific */ - /* interface by name. */ + /* get_interface :: The interface requesting function. */ /* */ typedef struct FT_Module_Class_ { @@ -144,7 +179,7 @@ FT_BEGIN_HEADER /* FT_Add_Module */ /* */ /* <Description> */ - /* Adds a new module to a given library instance. */ + /* Add a new module to a given library instance. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ @@ -153,7 +188,7 @@ FT_BEGIN_HEADER /* clazz :: A pointer to class descriptor for the module. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ @@ -170,7 +205,7 @@ FT_BEGIN_HEADER /* FT_Get_Module */ /* */ /* <Description> */ - /* Finds a module by its name. */ + /* Find a module by its name. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ @@ -178,7 +213,7 @@ FT_BEGIN_HEADER /* module_name :: The module's name (as an ASCII string). */ /* */ /* <Return> */ - /* A module handle. 0 if none was found. */ + /* A module handle. 0~if none was found. */ /* */ /* <Note> */ /* FreeType's internal modules aren't documented very well, and you */ @@ -195,7 +230,7 @@ FT_BEGIN_HEADER /* FT_Remove_Module */ /* */ /* <Description> */ - /* Removes a given module from a library instance. */ + /* Remove a given module from a library instance. */ /* */ /* <InOut> */ /* library :: A handle to a library object. */ @@ -204,7 +239,7 @@ FT_BEGIN_HEADER /* module :: A handle to a module object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The module object is destroyed by the function in case of success. */ @@ -224,6 +259,10 @@ FT_BEGIN_HEADER /* from a given memory object. It is thus possible to use libraries */ /* with distinct memory allocators within the same program. */ /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ /* <Input> */ /* memory :: A handle to the original memory object. */ /* */ @@ -231,7 +270,7 @@ FT_BEGIN_HEADER /* alibrary :: A pointer to handle of a new library object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_New_Library( FT_Memory memory, @@ -244,14 +283,14 @@ FT_BEGIN_HEADER /* FT_Done_Library */ /* */ /* <Description> */ - /* Discards a given library object. This closes all drivers and */ + /* Discard a given library object. This closes all drivers and */ /* discards all resource objects. */ /* */ /* <Input> */ /* library :: A handle to the target library. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); @@ -268,7 +307,7 @@ FT_BEGIN_HEADER /* FT_Set_Debug_Hook */ /* */ /* <Description> */ - /* Sets a debug hook function for debugging the interpreter of a font */ + /* Set a debug hook function for debugging the interpreter of a font */ /* format. */ /* */ /* <InOut> */ @@ -283,7 +322,7 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type 1 interpreter) are defined. */ + /* the TrueType and the Type~1 interpreter) are defined. */ /* */ /* Since the internal headers of FreeType are no longer installed, */ /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ @@ -301,7 +340,7 @@ FT_BEGIN_HEADER /* FT_Add_Default_Modules */ /* */ /* <Description> */ - /* Adds the set of default drivers to a given library object. */ + /* Add the set of default drivers to a given library object. */ /* This is only useful when you create a library object with */ /* @FT_New_Library (usually to plug a custom memory manager). */ /* */ @@ -362,7 +401,7 @@ FT_BEGIN_HEADER * 2.2 * */ - typedef enum + typedef enum FT_TrueTypeEngineType_ { FT_TRUETYPE_ENGINE_TYPE_NONE = 0, FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, @@ -377,7 +416,7 @@ FT_BEGIN_HEADER * FT_Get_TrueType_Engine_Type * * @description: - * Return a @FT_TrueTypeEngineType value to indicate which level of + * Return an @FT_TrueTypeEngineType value to indicate which level of * the TrueType virtual machine a given library instance supports. * * @input: diff --git a/lib/3rdparty/freetype/include/freetype/ftotval.h b/lib/3rdparty/freetype/include/freetype/ftotval.h index 7c488fdf465..027f2e88657 100644 --- a/lib/3rdparty/freetype/include/freetype/ftotval.h +++ b/lib/3rdparty/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,7 +56,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* This section contains the declaration of functions to validate */ - /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF). */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ /* */ /*************************************************************************/ @@ -86,8 +86,11 @@ FT_BEGIN_HEADER * FT_VALIDATE_JSTF :: * Validate JSTF table. * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * * FT_VALIDATE_OT :: - * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF). + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). * */ #define FT_VALIDATE_BASE 0x0100 @@ -95,12 +98,14 @@ FT_BEGIN_HEADER #define FT_VALIDATE_GPOS 0x0400 #define FT_VALIDATE_GSUB 0x0800 #define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 #define FT_VALIDATE_OT FT_VALIDATE_BASE | \ FT_VALIDATE_GDEF | \ FT_VALIDATE_GPOS | \ FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH /* */ @@ -140,7 +145,7 @@ FT_BEGIN_HEADER * A pointer to the JSTF table. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function only works with OpenType fonts, returning an error diff --git a/lib/3rdparty/freetype/include/freetype/ftoutln.h b/lib/3rdparty/freetype/include/freetype/ftoutln.h index 786ae13ed8f..2829a05ca30 100644 --- a/lib/3rdparty/freetype/include/freetype/ftoutln.h +++ b/lib/3rdparty/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,15 +84,14 @@ FT_BEGIN_HEADER /* FT_Outline_Decompose */ /* */ /* <Description> */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and BĂ©zier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and BĂ©zier arcs. This function also emits `move to' */ + /* operations to indicate the start of new contours in the outline. */ /* */ /* <Input> */ /* outline :: A pointer to the source target. */ /* */ - /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* func_interface :: A table of `emitters', i.e., function pointers */ /* called during decomposition to indicate path */ /* operations. */ /* */ @@ -103,7 +102,7 @@ FT_BEGIN_HEADER /* decomposition. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, @@ -117,7 +116,7 @@ FT_BEGIN_HEADER /* FT_Outline_New */ /* */ /* <Description> */ - /* Creates a new outline of a given size. */ + /* Create a new outline of a given size. */ /* */ /* <Input> */ /* library :: A handle to the library object from where the */ @@ -130,11 +129,10 @@ FT_BEGIN_HEADER /* numContours :: The maximal number of contours within the outline. */ /* */ /* <Output> */ - /* anoutline :: A handle to the new outline. NULL in case of */ - /* error. */ + /* anoutline :: A handle to the new outline. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The reason why this function takes a `library' parameter is simply */ @@ -160,7 +158,7 @@ FT_BEGIN_HEADER /* FT_Outline_Done */ /* */ /* <Description> */ - /* Destroys an outline created with @FT_Outline_New. */ + /* Destroy an outline created with @FT_Outline_New. */ /* */ /* <Input> */ /* library :: A handle of the library object used to allocate the */ @@ -169,7 +167,7 @@ FT_BEGIN_HEADER /* outline :: A pointer to the outline object to be discarded. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If the outline's `owner' field is not set, only the outline */ @@ -200,7 +198,7 @@ FT_BEGIN_HEADER /* outline :: A handle to a source outline. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Check( FT_Outline* outline ); @@ -212,7 +210,7 @@ FT_BEGIN_HEADER /* FT_Outline_Get_CBox */ /* */ /* <Description> */ - /* Returns an outline's `control box'. The control box encloses all */ + /* Return an outline's `control box'. The control box encloses all */ /* the outline's points, including BĂ©zier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ @@ -240,7 +238,7 @@ FT_BEGIN_HEADER /* FT_Outline_Translate */ /* */ /* <Description> */ - /* Applies a simple translation to the points of an outline. */ + /* Apply a simple translation to the points of an outline. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ @@ -262,7 +260,7 @@ FT_BEGIN_HEADER /* FT_Outline_Copy */ /* */ /* <Description> */ - /* Copies an outline into another one. Both objects must have the */ + /* Copy an outline into another one. Both objects must have the */ /* same sizes (number of points & number of contours) when this */ /* function is called. */ /* */ @@ -273,7 +271,7 @@ FT_BEGIN_HEADER /* target :: A handle to the target outline. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Copy( const FT_Outline* source, @@ -286,7 +284,7 @@ FT_BEGIN_HEADER /* FT_Outline_Transform */ /* */ /* <Description> */ - /* Applies a simple 2x2 matrix to all of an outline's points. Useful */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ /* for applying rotations, slanting, flipping, etc. */ /* */ /* <InOut> */ @@ -310,7 +308,7 @@ FT_BEGIN_HEADER /* FT_Outline_Embolden */ /* */ /* <Description> */ - /* Emboldens an outline. The new outline will be at most 4 times */ + /* Embolden an outline. The new outline will be at most 4~times */ /* `strength' pixels wider and higher. You may think of the left and */ /* bottom borders as unchanged. */ /* */ @@ -325,7 +323,7 @@ FT_BEGIN_HEADER /* 26.6 pixel format. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The used algorithm to increase or decrease the thickness of the */ @@ -333,6 +331,9 @@ FT_BEGIN_HEADER /* situations like acute angles or intersections are sometimes */ /* handled incorrectly. */ /* */ + /* If you need `better' metrics values you should call */ + /* @FT_Outline_Get_CBox ot @FT_Outline_Get_BBox. */ + /* */ /* Example call: */ /* */ /* { */ @@ -352,14 +353,14 @@ FT_BEGIN_HEADER /* FT_Outline_Reverse */ /* */ /* <Description> */ - /* Reverses the drawing direction of an outline. This is used to */ + /* Reverse the drawing direction of an outline. This is used to */ /* ensure consistent fill conventions for mirrored glyphs. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ /* */ /* <Note> */ - /* This functions toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ /* the outline's `flags' field. */ /* */ /* It shouldn't be used by a normal client application, unless it */ @@ -375,7 +376,7 @@ FT_BEGIN_HEADER /* FT_Outline_Get_Bitmap */ /* */ /* <Description> */ - /* Renders an outline within a bitmap. The outline's image is simply */ + /* Render an outline within a bitmap. The outline's image is simply */ /* OR-ed to the target bitmap. */ /* */ /* <Input> */ @@ -387,14 +388,19 @@ FT_BEGIN_HEADER /* abitmap :: A pointer to the target bitmap descriptor. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ /* */ /* It will use the raster corresponding to the default glyph format. */ /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, FT_Outline* outline, @@ -407,8 +413,8 @@ FT_BEGIN_HEADER /* FT_Outline_Render */ /* */ /* <Description> */ - /* Renders an outline within a bitmap using the current scan-convert. */ - /* This functions uses an @FT_Raster_Params structure as an argument, */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This function uses an @FT_Raster_Params structure as an argument, */ /* allowing advanced features like direct composition, translucency, */ /* etc. */ /* */ @@ -422,7 +428,7 @@ FT_BEGIN_HEADER /* describe the rendering operation. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You should know what you are doing and how @FT_Raster_Params works */ @@ -432,6 +438,11 @@ FT_BEGIN_HEADER /* converter is called, which means that the value you give to it is */ /* actually ignored. */ /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Render( FT_Library library, FT_Outline* outline, @@ -446,7 +457,7 @@ FT_BEGIN_HEADER * @description: * A list of values used to describe an outline's contour orientation. * - * The TrueType and Postscript specifications use different conventions + * The TrueType and PostScript specifications use different conventions * to determine whether outline contours should be filled or unfilled. * * @values: @@ -455,7 +466,7 @@ FT_BEGIN_HEADER * be filled, and counter-clockwise ones must be unfilled. * * FT_ORIENTATION_POSTSCRIPT :: - * According to the Postscript specification, counter-clockwise contours + * According to the PostScript specification, counter-clockwise contours * must be filled, and clockwise ones must be unfilled. * * FT_ORIENTATION_FILL_RIGHT :: @@ -465,7 +476,7 @@ FT_BEGIN_HEADER * * FT_ORIENTATION_FILL_LEFT :: * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to - * remember that in Postscript, everything that is to the left of + * remember that in PostScript, everything that is to the left of * the drawing direction of a contour must be filled. * * FT_ORIENTATION_NONE :: @@ -473,7 +484,7 @@ FT_BEGIN_HEADER * the glyph have different orientation. * */ - typedef enum + typedef enum FT_Orientation_ { FT_ORIENTATION_TRUETYPE = 0, FT_ORIENTATION_POSTSCRIPT = 1, diff --git a/lib/3rdparty/freetype/include/freetype/ftpfr.h b/lib/3rdparty/freetype/include/freetype/ftpfr.h index e2801fd0f98..0b7b7d427c9 100644 --- a/lib/3rdparty/freetype/include/freetype/ftpfr.h +++ b/lib/3rdparty/freetype/include/freetype/ftpfr.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,8 +62,8 @@ FT_BEGIN_HEADER * * @output: * aoutline_resolution :: - * Outline resolution. This is equivalent to `face->units_per_EM'. - * Optional (parameter can be NULL). + * Outline resolution. This is equivalent to `face->units_per_EM' + * for non-PFR fonts. Optional (parameter can be NULL). * * ametrics_resolution :: * Metrics resolution. This is equivalent to `outline_resolution' @@ -73,14 +73,14 @@ FT_BEGIN_HEADER * A 16.16 fixed-point number used to scale distance expressed * in metrics units to device sub-pixels. This is equivalent to * `face->size->x_scale', but for metrics only. Optional (parameter - * can be NULL) + * can be NULL). * * ametrics_y_scale :: * Same as `ametrics_x_scale' but for the vertical direction. - * optional (parameter can be NULL) + * optional (parameter can be NULL). * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * If the input face is not a PFR, this function will return an error. @@ -115,7 +115,7 @@ FT_BEGIN_HEADER * avector :: A kerning vector. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function always return distances in original PFR metrics @@ -150,7 +150,7 @@ FT_BEGIN_HEADER * aadvance :: The glyph advance in metrics units. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics diff --git a/lib/3rdparty/freetype/include/freetype/ftrender.h b/lib/3rdparty/freetype/include/freetype/ftrender.h index 5b07f08c2de..41c31eac48c 100644 --- a/lib/3rdparty/freetype/include/freetype/ftrender.h +++ b/lib/3rdparty/freetype/include/freetype/ftrender.h @@ -124,27 +124,32 @@ FT_BEGIN_HEADER /* The renderer module class descriptor. */ /* */ /* <Fields> */ - /* root :: The root @FT_Module_Class fields. */ + /* root :: The root @FT_Module_Class fields. */ /* */ - /* glyph_format :: The glyph image format this renderer handles. */ + /* glyph_format :: The glyph image format this renderer handles. */ /* */ - /* render_glyph :: A method used to render the image that is in a */ - /* given glyph slot into a bitmap. */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ /* */ - /* set_mode :: A method used to pass additional parameters. */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ /* */ - /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. This */ - /* is a pointer to its raster's class. */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ /* */ - /* raster :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. This */ - /* is a pointer to the corresponding raster object, */ - /* if any. */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + /* raster :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to the corresponding raster */ + /* object, if any. */ /* */ typedef struct FT_Renderer_Class_ { - FT_Module_Class root; + FT_Module_Class root; - FT_Glyph_Format glyph_format; + FT_Glyph_Format glyph_format; FT_Renderer_RenderFunc render_glyph; FT_Renderer_TransformFunc transform_glyph; @@ -162,7 +167,7 @@ FT_BEGIN_HEADER /* FT_Get_Renderer */ /* */ /* <Description> */ - /* Retrieves the current renderer for a given glyph format. */ + /* Retrieve the current renderer for a given glyph format. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ @@ -170,7 +175,7 @@ FT_BEGIN_HEADER /* format :: The glyph format. */ /* */ /* <Return> */ - /* A renderer handle. 0 if none found. */ + /* A renderer handle. 0~if none found. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ @@ -190,7 +195,7 @@ FT_BEGIN_HEADER /* FT_Set_Renderer */ /* */ /* <Description> */ - /* Sets the current renderer to use, and set additional mode. */ + /* Set the current renderer to use, and set additional mode. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ @@ -203,7 +208,7 @@ FT_BEGIN_HEADER /* parameters :: Additional parameters. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* In case of success, the renderer will be used to convert glyph */ diff --git a/lib/3rdparty/freetype/include/freetype/ftsizes.h b/lib/3rdparty/freetype/include/freetype/ftsizes.h index 622df162d2c..3e548cc39f3 100644 --- a/lib/3rdparty/freetype/include/freetype/ftsizes.h +++ b/lib/3rdparty/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2001, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -89,7 +89,7 @@ FT_BEGIN_HEADER /* asize :: A handle to a new size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You need to call @FT_Activate_Size in order to select the new size */ @@ -115,7 +115,7 @@ FT_BEGIN_HEADER /* size :: A handle to a target size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Size( FT_Size size ); @@ -129,8 +129,8 @@ FT_BEGIN_HEADER /* <Description> */ /* Even though it is possible to create several size objects for a */ /* given face (see @FT_New_Size for details), functions like */ - /* @FT_Load_Glyph or @FT_Load_Char only use the last-created one to */ - /* determine the `current character pixel size'. */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one which has been */ + /* activated last to determine the `current character pixel size'. */ /* */ /* This function can be used to `activate' a previously created size */ /* object. */ @@ -139,7 +139,7 @@ FT_BEGIN_HEADER /* size :: A handle to a target size object. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If `face' is the size's parent face object, this function changes */ diff --git a/lib/3rdparty/freetype/include/freetype/ftsnames.h b/lib/3rdparty/freetype/include/freetype/ftsnames.h index 003cbcd129c..485e4e162e7 100644 --- a/lib/3rdparty/freetype/include/freetype/ftsnames.h +++ b/lib/3rdparty/freetype/include/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,7 +48,7 @@ FT_BEGIN_HEADER /* Access the names embedded in TrueType and OpenType files. */ /* */ /* <Description> */ - /* The TrueType and OpenType specification allow the inclusion of */ + /* The TrueType and OpenType specifications allow the inclusion of */ /* a special `names table' in font files. This table contains */ /* textual (and internationalized) information regarding the font, */ /* like family name, copyright, version, etc. */ @@ -114,7 +114,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Name_Count */ /* */ /* <Description> */ - /* Retrieves the number of name strings in the SFNT `name' table. */ + /* Retrieve the number of name strings in the SFNT `name' table. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ @@ -132,7 +132,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Name */ /* */ /* <Description> */ - /* Retrieves a string of the SFNT `name' table for a given index. */ + /* Retrieve a string of the SFNT `name' table for a given index. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ @@ -143,11 +143,12 @@ FT_BEGIN_HEADER /* aname :: The indexed @FT_SfntName structure. */ /* */ /* <Return> */ - /* FreeType error code. 0 means success. */ + /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ /* */ /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ /* `name' table entries, then do a loop until you get the right */ @@ -159,6 +160,35 @@ FT_BEGIN_HEADER FT_SfntName *aname ); + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred family subfamily names in `name' + * table since OpenType version 1.4. For backwards compatibility with + * legacy systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred subfamily names in `name' table since + * OpenType version 1.4. For backwards compatibility with legacy + * systems which has 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/ftstroke.h b/lib/3rdparty/freetype/include/freetype/ftstroke.h index 738b43c1acc..3afb87df887 100644 --- a/lib/3rdparty/freetype/include/freetype/ftstroke.h +++ b/lib/3rdparty/freetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (specification). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,7 +84,7 @@ FT_BEGIN_HEADER * is too closed (this is useful to avoid unpleasant spikes * in beveled rendering). */ - typedef enum + typedef enum FT_Stroker_LineJoin_ { FT_STROKER_LINEJOIN_ROUND = 0, FT_STROKER_LINEJOIN_BEVEL, @@ -115,7 +115,7 @@ FT_BEGIN_HEADER * The end of lines is rendered as a square around the * last point. */ - typedef enum + typedef enum FT_Stroker_LineCap_ { FT_STROKER_LINECAP_BUTT = 0, FT_STROKER_LINECAP_ROUND, @@ -149,7 +149,7 @@ FT_BEGIN_HEADER * You can however use @FT_Outline_GetInsideBorder and * @FT_Outline_GetOutsideBorder to get these. */ - typedef enum + typedef enum FT_StrokerBorder_ { FT_STROKER_BORDER_LEFT = 0, FT_STROKER_BORDER_RIGHT @@ -171,7 +171,7 @@ FT_BEGIN_HEADER * The source outline handle. * * @return: - * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid * outlines. */ FT_EXPORT( FT_StrokerBorder ) @@ -216,7 +216,7 @@ FT_BEGIN_HEADER * A new stroker object handle. NULL in case of error. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_New( FT_Library library, @@ -249,7 +249,7 @@ FT_BEGIN_HEADER * expressed as 16.16 fixed point value. * * @note: - * The radius is expressed in the same units that the outline + * The radius is expressed in the same units as the outline * coordinates. */ FT_EXPORT( void ) @@ -297,18 +297,18 @@ FT_BEGIN_HEADER * The source outline. * * opened :: - * A boolean. If 1, the outline is treated as an open path instead + * A boolean. If~1, the outline is treated as an open path instead * of a closed one. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: - * If `opened' is 0 (the default), the outline is treated as a closed - * path, and the stroker will generate two distinct `border' outlines. + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. * - * If `opened' is 1, the outline is processed as an open path, and the - * stroker will generate a single `stroke' outline. + * If `opened' is~1, the outline is processed as an open path, and the + * stroker generates a single `stroke' outline. * * This function calls @FT_Stroker_Rewind automatically. */ @@ -334,10 +334,10 @@ FT_BEGIN_HEADER * A pointer to the start vector. * * open :: - * A boolean. If 1, the sub-path is treated as an open one. + * A boolean. If~1, the sub-path is treated as an open one. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * This function is useful when you need to stroke a path that is @@ -362,11 +362,11 @@ FT_BEGIN_HEADER * The target stroker handle. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function after @FT_Stroker_BeginSubPath. - * If the subpath was not `opened', this function will `draw' a + * If the subpath was not `opened', this function `draws' a * single line segment to the start position when needed. */ FT_EXPORT( FT_Error ) @@ -390,7 +390,7 @@ FT_BEGIN_HEADER * A pointer to the destination point. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and @@ -421,7 +421,7 @@ FT_BEGIN_HEADER * A pointer to the destination point. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and @@ -456,7 +456,7 @@ FT_BEGIN_HEADER * A pointer to the destination point. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and @@ -476,7 +476,7 @@ FT_BEGIN_HEADER * * @description: * Call this function once you have finished parsing your paths - * with the stroker. It will return the number of points and + * with the stroker. It returns the number of points and * contours necessary to export one of the `border' or `stroke' * outlines generated by the stroker. * @@ -495,7 +495,7 @@ FT_BEGIN_HEADER * The number of contours. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * When an outline, or a sub-path, is `closed', the stroker generates @@ -525,8 +525,8 @@ FT_BEGIN_HEADER * export the corresponding border to your own @FT_Outline * structure. * - * Note that this function will append the border points and - * contours to your outline, but will not try to resize its + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its * arrays. * * @input: @@ -583,7 +583,7 @@ FT_BEGIN_HEADER * The number of contours. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_GetCounts( FT_Stroker stroker, @@ -598,10 +598,10 @@ FT_BEGIN_HEADER * * @description: * Call this function after @FT_Stroker_GetBorderCounts to - * export the all borders to your own @FT_Outline structure. + * export all borders to your own @FT_Outline structure. * - * Note that this function will append the border points and - * contours to your outline, but will not try to resize its + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its * arrays. * * @input: @@ -649,11 +649,11 @@ FT_BEGIN_HEADER * A stroker handle. * * destroy :: - * A Boolean. If 1, the source glyph object is destroyed + * A Boolean. If~1, the source glyph object is destroyed * on success. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source glyph is untouched in case of error. @@ -682,15 +682,15 @@ FT_BEGIN_HEADER * A stroker handle. * * inside :: - * A Boolean. If 1, return the inside border, otherwise + * A Boolean. If~1, return the inside border, otherwise * the outside border. * * destroy :: - * A Boolean. If 1, the source glyph object is destroyed + * A Boolean. If~1, the source glyph object is destroyed * on success. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * The source glyph is untouched in case of error. diff --git a/lib/3rdparty/freetype/include/freetype/ftsynth.h b/lib/3rdparty/freetype/include/freetype/ftsynth.h index 36984bf1a7b..a068b7928d6 100644 --- a/lib/3rdparty/freetype/include/freetype/ftsynth.h +++ b/lib/3rdparty/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2006 by */ +/* Copyright 2000-2001, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,7 +23,7 @@ /*************************************************************************/ /*************************************************************************/ /********* *********/ - /********* WARNING, THIS IS ALPHA CODE, THIS API *********/ + /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ /********* FREETYPE DEVELOPMENT TEAM *********/ /********* *********/ @@ -34,6 +34,13 @@ /*************************************************************************/ + /* Main reason for not lifting the functions in this module to a */ + /* `standard' API is that the used parameters for emboldening and */ + /* slanting are not configurable. Consider the functions as a */ + /* code resource which should be copied into the application and */ + /* adapted to the particular needs. */ + + #ifndef __FTSYNTH_H__ #define __FTSYNTH_H__ @@ -50,20 +57,20 @@ FT_BEGIN_HEADER - /* Make sure slot owns slot->bitmap. */ - FT_EXPORT( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); - - /* Do not use this function directly! Copy the code to */ - /* your application and modify it to suit your need. */ + /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* taste). This function is actually a convenience function, providing */ + /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ + /* */ + /* For emboldened outlines the metrics are estimates only; if you need */ + /* precise values you should call @FT_Outline_Get_CBox. */ FT_EXPORT( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); - + /* Slant an outline glyph to the right by about 12 degrees. */ FT_EXPORT( void ) FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); - /* */ + /* */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/ftsystem.h b/lib/3rdparty/freetype/include/freetype/ftsystem.h index 59cd0198221..a95b2c76b61 100644 --- a/lib/3rdparty/freetype/include/freetype/ftsystem.h +++ b/lib/3rdparty/freetype/include/freetype/ftsystem.h @@ -82,7 +82,7 @@ FT_BEGIN_HEADER * The size in bytes to allocate. * * @return: - * Address of new memory block. 0 in case of failure. + * Address of new memory block. 0~in case of failure. * */ typedef void* @@ -133,7 +133,7 @@ FT_BEGIN_HEADER * The block's current address. * * @return: - * New block address. 0 in case of memory shortage. + * New block address. 0~in case of memory shortage. * * @note: * In case of error, the old block must still be available. @@ -152,7 +152,7 @@ FT_BEGIN_HEADER * FT_MemoryRec * * @description: - * A structure used to describe a given memory manager to FreeType 2. + * A structure used to describe a given memory manager to FreeType~2. * * @fields: * user :: @@ -240,7 +240,7 @@ FT_BEGIN_HEADER * * @note: * This function might be called to perform a seek or skip operation - * with a `count' of 0. + * with a `count' of~0. * */ typedef unsigned long diff --git a/lib/3rdparty/freetype/include/freetype/fttypes.h b/lib/3rdparty/freetype/include/freetype/fttypes.h index 2340bacd310..a57ffa69bd8 100644 --- a/lib/3rdparty/freetype/include/freetype/fttypes.h +++ b/lib/3rdparty/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType simple types definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,7 @@ FT_BEGIN_HEADER /* The basic data types defined by the library. */ /* */ /* <Description> */ - /* This section contains the basic data types defined by FreeType 2, */ + /* This section contains the basic data types defined by FreeType~2, */ /* ranging from simple scalar types to bitmap descriptors. More */ /* font-specific structures are defined in a different section. */ /* */ @@ -53,6 +53,10 @@ FT_BEGIN_HEADER /* FT_Char */ /* FT_Int */ /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ /* FT_Short */ /* FT_UShort */ /* FT_Long */ @@ -95,7 +99,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A typedef of unsigned char, used for simple booleans. As usual, */ - /* values 1 and 0 represent true and false, respectively. */ + /* values 1 and~0 represent true and false, respectively. */ /* */ typedef unsigned char FT_Bool; @@ -163,7 +167,7 @@ FT_BEGIN_HEADER /* FT_Tag */ /* */ /* <Description> */ - /* A typedef for 32bit tags (as used in the SFNT format). */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ /* */ typedef FT_UInt32 FT_Tag; @@ -286,7 +290,7 @@ FT_BEGIN_HEADER /* FT_Error */ /* */ /* <Description> */ - /* The FreeType error code type. A value of 0 is always interpreted */ + /* The FreeType error code type. A value of~0 is always interpreted */ /* as a successful operation. */ /* */ typedef int FT_Error; @@ -309,7 +313,7 @@ FT_BEGIN_HEADER /* FT_Offset */ /* */ /* <Description> */ - /* This is equivalent to the ANSI C `size_t' type, i.e., the largest */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ /* _unsigned_ integer type used to express a file size or position, */ /* or a memory block size. */ /* */ @@ -322,7 +326,7 @@ FT_BEGIN_HEADER /* FT_PtrDist */ /* */ /* <Description> */ - /* This is equivalent to the ANSI C `ptrdiff_t' type, i.e., the */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ /* largest _signed_ integer type used to express the distance */ /* between two pointers. */ /* */ @@ -409,7 +413,7 @@ FT_BEGIN_HEADER /* FT_Generic_Finalizer */ /* */ /* <Description> */ - /* Describes a function used to destroy the `client' data of any */ + /* Describe a function used to destroy the `client' data of any */ /* FreeType object. See the description of the @FT_Generic type for */ /* details of usage. */ /* */ @@ -466,10 +470,11 @@ FT_BEGIN_HEADER /* TrueType tables into an unsigned long to be used within FreeType. */ /* */ /* <Note> */ - /* The produced values *must* be 32bit integers. Don't redefine this */ - /* macro. */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ /* */ #define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ ( ( (FT_ULong)_x1 << 24 ) | \ ( (FT_ULong)_x2 << 16 ) | \ ( (FT_ULong)_x3 << 8 ) | \ diff --git a/lib/3rdparty/freetype/include/freetype/ftwinfnt.h b/lib/3rdparty/freetype/include/freetype/ftwinfnt.h index a0063cc7356..ea33353536e 100644 --- a/lib/3rdparty/freetype/include/freetype/ftwinfnt.h +++ b/lib/3rdparty/freetype/include/freetype/ftwinfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows fnt-specific data. */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -111,11 +111,11 @@ FT_BEGIN_HEADER * ordering and minor deviations). * * FT_WinFNT_ID_CP949 :: - * A superset of Korean Hangul KS C 5601-1987 (with different + * A superset of Korean Hangul KS~C 5601-1987 (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP950 :: - * A superset of traditional Chinese Big 5 ETen (with different + * A superset of traditional Chinese Big~5 ETen (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP1250 :: @@ -219,36 +219,47 @@ FT_BEGIN_HEADER FT_UShort color_table_offset; FT_ULong reserved1[4]; - } FT_WinFNT_HeaderRec, *FT_WinFNT_Header; + } FT_WinFNT_HeaderRec; - /********************************************************************** - * - * @function: - * FT_Get_WinFNT_Header - * - * @description: - * Retrieve a Windows FNT font info header. - * - * @input: - * face :: A handle to the input face. - * - * @output: - * aheader :: The WinFNT header. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * This function only works with Windows FNT faces, returning an error - * otherwise. - */ + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ FT_EXPORT( FT_Error ) FT_Get_WinFNT_Header( FT_Face face, FT_WinFNT_HeaderRec *aheader ); - /* */ + /* */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/ftxf86.h b/lib/3rdparty/freetype/include/freetype/ftxf86.h index ea82abb0842..8c68afdcc58 100644 --- a/lib/3rdparty/freetype/include/freetype/ftxf86.h +++ b/lib/3rdparty/freetype/include/freetype/ftxf86.h @@ -49,6 +49,9 @@ FT_BEGIN_HEADER /* however, there are special cases (like in PDF devices) where it is */ /* important to differentiate, in spite of FreeType's uniform API. */ /* */ + /* This function is in the X11/xf86 namespace for historical reasons */ + /* and in no way depends on that windowing system. */ + /* */ /*************************************************************************/ @@ -60,8 +63,8 @@ FT_BEGIN_HEADER /* <Description> */ /* Return a string describing the format of a given face, using values */ /* which can be used as an X11 FONT_PROPERTY. Possible values are */ - /* `TrueType', `Type 1', `BDF', `PCF', `Type 42', `CID Type 1', `CFF', */ - /* `PFR', and `Windows FNT'. */ + /* `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */ + /* `PFR', and `Windows~FNT'. */ /* */ /* <Input> */ /* face :: */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/autohint.h b/lib/3rdparty/freetype/include/freetype/internal/autohint.h index ee004022f9d..7e3a08a0511 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/autohint.h +++ b/lib/3rdparty/freetype/include/freetype/internal/autohint.h @@ -196,6 +196,32 @@ FT_BEGIN_HEADER } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \ + done_global_hints_, load_glyph_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_AutoHinter_ServiceRec class_ = \ + { \ + reset_face_, get_global_hints_, done_global_hints_, load_glyph_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \ + done_global_hints_, load_glyph_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_AutoHinter_ServiceRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->reset_face = reset_face_; \ + clazz->get_global_hints = get_global_hints_; \ + clazz->done_global_hints = done_global_hints_; \ + clazz->load_glyph = load_glyph_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h b/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h index c7e9901ebaf..f8b4324777e 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -111,6 +111,31 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ + /* + * A variant of FT_Matrix_Multiply which scales its result afterwards. + * The idea is that both `a' and `b' are scaled by factors of 10 so that + * the values are as precise as possible to get a correct result during + * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of + * `a' and `b', respectively, then the scaling factor of the result is + * `sa*sb'. + */ + FT_BASE( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. + */ + + FT_BASE( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ); + + /* * Return -1, 0, or +1, depending on the orientation of a given corner. * We use the Cartesian coordinate system, with positive vertical values @@ -140,6 +165,7 @@ FT_BEGIN_HEADER #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) #define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ : ( -( ( 32 - (x) ) & -64 ) ) ) diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h b/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h index 15627147b8e..7baae3531d5 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -54,7 +54,7 @@ FT_BEGIN_HEADER #define FT_TRACE_DEF( x ) trace_ ## x , /* defining the enumeration */ - typedef enum + typedef enum FT_Trace_ { #include FT_INTERNAL_TRACE_H trace_count @@ -92,7 +92,7 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_TRACE */ -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ +#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */ #endif /* !FT_DEBUG_LEVEL_TRACE */ @@ -146,10 +146,12 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* You need two opening resp. closing parentheses! */ + /* You need two opening and closing parentheses! */ /* */ /* Example: FT_TRACE0(( "Value is %i", foo )) */ /* */ + /* Output of the FT_TRACEX macros is sent to stderr. */ + /* */ /*************************************************************************/ #define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) @@ -164,7 +166,9 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Define the FT_ERROR macro */ + /* Define the FT_ERROR macro. */ + /* */ + /* Output of this macro is sent to stderr. */ /* */ /*************************************************************************/ @@ -174,14 +178,14 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_ERROR */ -#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ +#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */ #endif /* !FT_DEBUG_LEVEL_ERROR */ /*************************************************************************/ /* */ - /* Define the FT_ASSERT macro */ + /* Define the FT_ASSERT macro. */ /* */ /*************************************************************************/ @@ -197,28 +201,30 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_ERROR */ -#define FT_ASSERT( condition ) do ; while ( 0 ) +#define FT_ASSERT( condition ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_ERROR */ /*************************************************************************/ /* */ - /* Define `FT_Message' and `FT_Panic' when needed */ + /* Define `FT_Message' and `FT_Panic' when needed. */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_ERROR -#include "stdio.h" /* for vprintf() */ +#include "stdio.h" /* for vfprintf() */ /* print a message */ FT_BASE( void ) - FT_Message( const char* fmt, ... ); + FT_Message( const char* fmt, + ... ); /* print a message and exit */ FT_BASE( void ) - FT_Panic( const char* fmt, ... ); + FT_Panic( const char* fmt, + ... ); #endif /* FT_DEBUG_LEVEL_ERROR */ @@ -229,8 +235,8 @@ FT_BEGIN_HEADER #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ - /* we disable the warning `conditional expression is constant' here */ - /* in order to compile cleanly with the maximum level of warnings */ + /* We disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings. */ #pragma warning( disable : 4127 ) #endif /* _MSC_VER */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h b/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h index 97f3fd04d90..1d06997bd18 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftdriver.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,6 +91,7 @@ FT_BEGIN_HEADER (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, FT_Long charcode ); + typedef FT_Error (*FT_Face_GetKerningFunc)( FT_Face face, FT_UInt left_glyph, @@ -104,11 +105,11 @@ FT_BEGIN_HEADER typedef FT_Error - (*FT_Face_GetAdvancesFunc)( FT_Face face, - FT_UInt first, - FT_UInt count, - FT_Bool vertical, - FT_UShort* advances ); + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ); /*************************************************************************/ @@ -145,10 +146,6 @@ FT_BEGIN_HEADER /* load_glyph :: A function handle to load a glyph to a slot. */ /* This field is mandatory! */ /* */ - /* get_char_index :: A function handle to return the glyph index of */ - /* a given character for a given charmap. This */ - /* field is mandatory! */ - /* */ /* get_kerning :: A function handle to return the unscaled */ /* kerning for a given pair of glyphs. Can be */ /* set to 0 if the format doesn't support */ @@ -180,8 +177,8 @@ FT_BEGIN_HEADER /* to 0 if the scaling done in the base layer */ /* suffices. */ /* <Note> */ - /* Most function pointers, with the exception of `load_glyph' and */ - /* `get_char_index' can be set to 0 to indicate a default behaviour. */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ /* */ typedef struct FT_Driver_ClassRec_ { @@ -243,6 +240,179 @@ FT_BEGIN_HEADER #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_DRIVER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Driver_ClassRec stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_DRIVER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Driver_ClassRec struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \ + a_, b_, +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) +#endif + +#define FT_DECLARE_DRIVER(class_) \ + FT_CALLBACK_TABLE \ + const FT_Driver_ClassRec class_; + +#define FT_DEFINE_DRIVER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + face_object_size_, size_object_size_, \ + slot_object_size_, init_face_, done_face_, \ + init_size_, done_size_, init_slot_, done_slot_, \ + old_set_char_sizes_, old_set_pixel_sizes_, \ + load_glyph_, get_kerning_, attach_file_, \ + get_advances_, request_size_, select_size_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Driver_ClassRec class_ = \ + { \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \ + init_,done_,get_interface_) \ + \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + \ + init_face_, \ + done_face_, \ + \ + init_size_, \ + done_size_, \ + \ + init_slot_, \ + done_slot_, \ + \ + FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \ + \ + load_glyph_, \ + \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + \ + request_size_, \ + select_size_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \ + clazz->set_char_sizes = a_; \ + clazz->set_pixel_sizes = b_; +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) +#endif + +#define FT_DECLARE_DRIVER(class_) FT_DECLARE_MODULE(class_) + +#define FT_DEFINE_DRIVER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + face_object_size_, size_object_size_, \ + slot_object_size_, init_face_, done_face_, \ + init_size_, done_size_, init_slot_, done_slot_, \ + old_set_char_sizes_, old_set_pixel_sizes_, \ + load_glyph_, get_kerning_, attach_file_, \ + get_advances_, request_size_, select_size_ ) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ + class_##_pic_free( library ); \ + if ( dclazz ) \ + FT_FREE( dclazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Driver_Class clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_, \ + init_,done_,get_interface_) \ + \ + clazz->face_object_size = face_object_size_; \ + clazz->size_object_size = size_object_size_; \ + clazz->slot_object_size = slot_object_size_; \ + \ + clazz->init_face = init_face_; \ + clazz->done_face = done_face_; \ + \ + clazz->init_size = init_size_; \ + clazz->done_size = done_size_; \ + \ + clazz->init_slot = init_slot_; \ + clazz->done_slot = done_slot_; \ + \ + FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \ + \ + clazz->load_glyph = load_glyph_; \ + \ + clazz->get_kerning = get_kerning_; \ + clazz->attach_file = attach_file_; \ + clazz->get_advances = get_advances_; \ + \ + clazz->request_size = request_size_; \ + clazz->select_size = select_size_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + return FT_Err_Ok; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h b/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h index 9f47c0b8c87..ce4dc6c9cc6 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftgloadr.h @@ -67,11 +67,11 @@ FT_BEGIN_HEADER typedef struct FT_GlyphLoadRec_ { - FT_Outline outline; /* outline */ - FT_Vector* extra_points; /* extra points table */ + FT_Outline outline; /* outline */ + FT_Vector* extra_points; /* extra points table */ FT_Vector* extra_points2; /* second extra points table */ - FT_UInt num_subglyphs; /* number of subglyphs */ - FT_SubGlyph subglyphs; /* subglyphs */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph subglyphs; /* subglyphs */ } FT_GlyphLoadRec, *FT_GlyphLoad; @@ -121,15 +121,15 @@ FT_BEGIN_HEADER FT_UInt n_contours ); -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (_count)) <= (int)(_loader)->max_points ) +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (unsigned long)(_count)) <= (_loader)->max_points ) -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (_count)) <= (int)(_loader)->max_contours ) +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (unsigned long)(_count)) <= (_loader)->max_contours ) #define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h b/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h index c6ddc42ea9b..2010ca90d7e 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftmemory.h @@ -333,8 +333,8 @@ FT_BEGIN_HEADER FT_ULong size, FT_Error *p_error ); -#define FT_MEM_STRDUP( dst, str ) \ - (dst) = ft_mem_strdup( memory, (const char*)(str), &error ) +#define FT_MEM_STRDUP( dst, str ) \ + (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) #define FT_STRDUP( dst, str ) \ FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h b/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h index 15b68d63f15..574cf582967 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,6 +35,7 @@ #include FT_INTERNAL_DRIVER_H #include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_PIC_H #ifdef FT_CONFIG_OPTION_INCREMENTAL #include FT_INCREMENTAL_H @@ -160,6 +161,31 @@ FT_BEGIN_HEADER (*FT_CMap_CharNextFunc)( FT_CMap cmap, FT_UInt32 *achar_code ); + typedef FT_UInt + (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, + FT_CMap unicode_cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_Bool + (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_UInt32 * + (*FT_CMap_VariantListFunc)( FT_CMap cmap, + FT_Memory mem ); + + typedef FT_UInt32 * + (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 char_code ); + + typedef FT_UInt32 * + (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 variant_selector ); + typedef struct FT_CMap_ClassRec_ { @@ -169,8 +195,56 @@ FT_BEGIN_HEADER FT_CMap_CharIndexFunc char_index; FT_CMap_CharNextFunc char_next; + /* Subsequent entries are special ones for format 14 -- the variant */ + /* selector subtable which behaves like no other */ + + FT_CMap_CharVarIndexFunc char_var_index; + FT_CMap_CharVarIsDefaultFunc char_var_default; + FT_CMap_VariantListFunc variant_list; + FT_CMap_CharVariantListFunc charvariant_list; + FT_CMap_VariantCharListFunc variantchar_list; + } FT_CMap_ClassRec; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_CMAP_CLASS(class_) \ + FT_CALLBACK_TABLE const FT_CMap_ClassRec class_; + +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_CMap_ClassRec class_ = \ + { \ + size_, init_, done_, char_index_, char_next_, char_var_index_, \ + char_var_default_, variant_list_, charvariant_list_, variantchar_list_ \ + }; +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_CMAP_CLASS(class_) \ + void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec* clazz); + +#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_CMap_ClassRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->size = size_; \ + clazz->init = init_; \ + clazz->done = done_; \ + clazz->char_index = char_index_; \ + clazz->char_next = char_next_; \ + clazz->char_var_index = char_var_index_; \ + clazz->char_var_default = char_var_default_; \ + clazz->variant_list = variant_list_; \ + clazz->charvariant_list = charvariant_list_; \ + clazz->variantchar_list = variantchar_list_; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ /* create a new charmap and add it to charmap->face */ FT_BASE( FT_Error ) @@ -306,7 +380,28 @@ FT_BEGIN_HEADER } FT_GlyphSlot_InternalRec; +#if 0 + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Size */ + /* object. Currently, it's empty. */ + /* */ + /*************************************************************************/ + + typedef struct FT_Size_InternalRec_ + { + /* empty */ + + } FT_Size_InternalRec; + +#endif + + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -710,6 +805,10 @@ FT_BEGIN_HEADER /* */ /* debug_hooks :: XXX */ /* */ + /* pic_container :: Contains global structs and tables, instead */ + /* of defining them globallly. */ + /* */ + typedef struct FT_LibraryRec_ { FT_Memory memory; /* library's memory manager */ @@ -740,6 +839,10 @@ FT_BEGIN_HEADER FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif +#ifdef FT_CONFIG_OPTION_PIC + FT_PIC_Container pic_container; +#endif + } FT_LibraryRec; @@ -811,6 +914,484 @@ FT_BEGIN_HEADER FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; #endif + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftimage.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_OUTLINE_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Outline_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ + cubic_to_, shift_, delta_) \ + static FT_Error \ + Init_Class_##class_( FT_Outline_Funcs* clazz ) \ + { \ + clazz->move_to = move_to_; \ + clazz->line_to = line_to_; \ + clazz->conic_to = conic_to_; \ + clazz->cubic_to = cubic_to_; \ + clazz->shift = shift_; \ + clazz->delta = delta_; \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_RASTER_FUNCS */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Raster_Funcs struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, raster_done_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, raster_render_, raster_done_) \ + void \ + FT_Init_Class_##class_( FT_Raster_Funcs* clazz ) \ + { \ + clazz->glyph_format = glyph_format_; \ + clazz->raster_new = raster_new_; \ + clazz->raster_reset = raster_reset_; \ + clazz->raster_set_mode = raster_set_mode_; \ + clazz->raster_render = raster_render_; \ + clazz->raster_done = raster_done_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftrender.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_GLYPH */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Glyph_Class struct. */ + /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ + /* called with a pre-allocated stracture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \ + transform_, bbox_, prepare_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Glyph_Class class_ = \ + { \ + size_, format_, init_, done_, copy_, transform_, bbox_, prepare_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_, \ + transform_, bbox_, prepare_) \ + void \ + FT_Init_Class_##class_( FT_Glyph_Class* clazz ) \ + { \ + clazz->glyph_size = size_; \ + clazz->glyph_format = format_; \ + clazz->glyph_init = init_; \ + clazz->glyph_done = done_; \ + clazz->glyph_copy = copy_; \ + clazz->glyph_transform = transform_; \ + clazz->glyph_bbox = bbox_; \ + clazz->glyph_prepare = prepare_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_RENDERER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Renderer_Class stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_RENDERER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Renderer_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_RENDERER(class_) \ + FT_EXPORT_VAR( const FT_Renderer_Class ) class_; + +#define FT_DEFINE_RENDERER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + glyph_format_, render_glyph_, transform_glyph_, \ + get_glyph_cbox_, set_mode_, raster_class_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Renderer_Class class_ = \ + { \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \ + interface_,init_,done_,get_interface_) \ + glyph_format_, \ + \ + render_glyph_, \ + transform_glyph_, \ + get_glyph_cbox_, \ + set_mode_, \ + \ + raster_class_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_RENDERER(class_) FT_DECLARE_MODULE(class_) + +#define FT_DEFINE_RENDERER(class_, \ + flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_, \ + glyph_format_, render_glyph_, transform_glyph_, \ + get_glyph_cbox_, set_mode_, raster_class_ ) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz; \ + FT_Memory memory = library->memory; \ + class_##_pic_free( library ); \ + if ( rclazz ) \ + FT_FREE( rclazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Renderer_Class* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_, \ + interface_,init_,done_,get_interface_) \ + \ + clazz->glyph_format = glyph_format_; \ + \ + clazz->render_glyph = render_glyph_; \ + clazz->transform_glyph = transform_glyph_; \ + clazz->get_glyph_cbox = get_glyph_cbox_; \ + clazz->set_mode = set_mode_; \ + \ + clazz->raster_class = raster_class_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + return FT_Err_Ok; \ + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** PIC-Support Macros for ftmodapi.h ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef FT_CONFIG_OPTION_PIC + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Creator */ + /* */ + /* <Description> */ + /* A function used to create (allocate) a new module class object. */ + /* The object's members are initialized, but the module itself is */ + /* not. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* output_class :: Initialized with the newly allocated class. */ + /* */ + typedef FT_Error + (*FT_Module_Creator)( FT_Memory memory, + FT_Module_Class** output_class ); + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destroyer */ + /* */ + /* <Description> */ + /* A function used to destroy (deallocate) a module class object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* clazz :: Module class to destroy. */ + /* */ + typedef void + (*FT_Module_Destroyer)( FT_Memory memory, + FT_Module_Class* clazz ); + +#endif + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_MODULE */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of a */ + /* FT_Module_Class stract instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Module_Class struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated stracture is returned.*/ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* fcinit.c (ft_create_default_module_classes) already contains */ + /* a mechanism to call these functions for the default modules */ + /* described in ftmodule.h */ + /* */ + /* Notice that the created Create and Destroy functions call */ + /* pic_init and pic_free function to allow you to manually allocate */ + /* and initialize any additional global data, like module specific */ + /* interface, and put them in the global pic container defined in */ + /* ftpic.h. if you don't need them just implement the functions as */ + /* empty to resolve the link error. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ + /* <Macro> */ + /* FT_DEFINE_ROOT_MODULE */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Module_Class struct inside */ + /* another stract that contains it or in a function that initializes */ + /* that containing stract */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_MODULE(class_) \ + FT_CALLBACK_TABLE \ + const FT_Module_Class class_; \ + +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }, + +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Module_Class class_ = \ + { \ + flags_, \ + size_, \ + \ + name_, \ + version_, \ + requires_, \ + \ + interface_, \ + \ + init_, \ + done_, \ + get_interface_, \ + }; + + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_MODULE(class_) \ + FT_Error FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ); \ + void FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ); + +#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + clazz->root.module_flags = flags_; \ + clazz->root.module_size = size_; \ + clazz->root.module_name = name_; \ + clazz->root.module_version = version_; \ + clazz->root.module_requires = requires_; \ + \ + clazz->root.module_interface = interface_; \ + \ + clazz->root.module_init = init_; \ + clazz->root.module_done = done_; \ + clazz->root.get_interface = get_interface_; + +#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_, \ + interface_, init_, done_, get_interface_) \ + void class_##_pic_free( FT_Library library ); \ + FT_Error class_##_pic_init( FT_Library library ); \ + \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + class_##_pic_free( library ); \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Module_Class* clazz; \ + FT_Error error; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz) ) ) \ + return error; \ + error = class_##_pic_init( library ); \ + if(error) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + clazz->module_flags = flags_; \ + clazz->module_size = size_; \ + clazz->module_name = name_; \ + clazz->module_version = version_; \ + clazz->module_requires = requires_; \ + \ + clazz->module_interface = interface_; \ + \ + clazz->module_init = init_; \ + clazz->module_done = done_; \ + clazz->get_interface = get_interface_; \ + \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftpic.h b/lib/3rdparty/freetype/include/freetype/internal/ftpic.h new file mode 100644 index 00000000000..1b31957d702 --- /dev/null +++ b/lib/3rdparty/freetype/include/freetype/internal/ftpic.h @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* ftpic.h */ +/* */ +/* The FreeType position independent code services (declaration). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Modules that ordinarily have const global data that need address */ + /* can instead define pointers here. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTPIC_H__ +#define __FTPIC_H__ + + +FT_BEGIN_HEADER + +#ifdef FT_CONFIG_OPTION_PIC + + typedef struct FT_PIC_Container_ + { + /* pic containers for base */ + void* base; + /* pic containers for modules */ + void* autofit; + void* cff; + void* pshinter; + void* psnames; + void* raster; + void* sfnt; + void* smooth; + void* truetype; + } FT_PIC_Container; + + /* Initialize the various function tables, structs, etc. stored in the container. */ + FT_BASE( FT_Error ) + ft_pic_container_init( FT_Library library ); + + + /* Destroy the contents of the container. */ + FT_BASE( void ) + ft_pic_container_destroy( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h b/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h index 94402bcfa73..aa573c87054 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (specification). */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004, 2006, 2007 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,7 +34,19 @@ FT_BEGIN_HEADER /* Number of guessing rules supported in `FT_Raccess_Guess'. */ /* Don't forget to increment the number if you add a new guessing rule. */ -#define FT_RACCESS_N_RULES 8 +#define FT_RACCESS_N_RULES 9 + + + /* A structure to describe a reference in a resource by its resource ID */ + /* and internal offset. The `POST' resource expects to be concatenated */ + /* by the order of resource IDs instead of its appearance in the file. */ + + typedef struct FT_RFork_Ref_ + { + FT_UShort res_id; + FT_ULong offset; + + } FT_RFork_Ref; /*************************************************************************/ diff --git a/lib/3rdparty/freetype/include/freetype/internal/ftserv.h b/lib/3rdparty/freetype/include/freetype/internal/ftserv.h index 45d2fa91834..569b9f7e0e8 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/ftserv.h +++ b/lib/3rdparty/freetype/include/freetype/internal/ftserv.h @@ -163,6 +163,298 @@ FT_BEGIN_HEADER typedef const FT_ServiceDescRec* FT_ServiceDesc; + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6 */ + /* */ + /* <Description> */ + /* Used to initialize an array of FT_ServiceDescRec structs. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a Create funtion will need */ + /* to called with a pointer where the allocated array is returned. */ + /* And when it is no longer needed a Destroy function needs */ + /* to be called to release that allocation. */ + /* */ + /* These functions should be manyally called from the pic_init and */ + /* pic_free functions of your module (see FT_DEFINE_MODULE) */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the array will be */ + /* allocated in the global scope (or the scope where the macro */ + /* is used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {serv_id_5, serv_data_5}, \ + {NULL, NULL} \ + }; +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6) \ + static const FT_ServiceDescRec class_[] = \ + { \ + {serv_id_1, serv_data_1}, \ + {serv_id_2, serv_data_2}, \ + {serv_id_3, serv_data_3}, \ + {serv_id_4, serv_data_4}, \ + {serv_id_5, serv_data_5}, \ + {serv_id_6, serv_data_6}, \ + {NULL, NULL} \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = NULL; \ + clazz[1].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = NULL; \ + clazz[2].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = NULL; \ + clazz[3].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = NULL; \ + clazz[4].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4, \ + serv_data_4, serv_id_5, serv_data_5) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = NULL; \ + clazz[5].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6) \ + void \ + FT_Destroy_Class_##class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_##class_( FT_Library library, \ + FT_ServiceDescRec** output_class) \ + { \ + FT_ServiceDescRec* clazz; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) ) \ + return error; \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = NULL; \ + clazz[6].serv_data = NULL; \ + *output_class = clazz; \ + return FT_Err_Ok; \ + } +#endif /* FT_CONFIG_OPTION_PIC */ /* * Parse a list of FT_ServiceDescRec descriptors and look for @@ -301,6 +593,7 @@ FT_BEGIN_HEADER */ #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> #define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> #define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> diff --git a/lib/3rdparty/freetype/include/freetype/internal/fttrace.h b/lib/3rdparty/freetype/include/freetype/internal/fttrace.h index 81916fc6aea..e9b383a5881 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/fttrace.h +++ b/lib/3rdparty/freetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,16 +31,19 @@ FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ +FT_TRACE_DEF( gloader ) /* glyph loader (ftgloadr.c) */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ +FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ /* Cache sub-system */ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ +FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ @@ -48,6 +51,7 @@ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ +FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ /* TrueType driver components */ FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ @@ -58,6 +62,7 @@ FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ /* Type 1 driver components */ +FT_TRACE_DEF( t1afm ) FT_TRACE_DEF( t1driver ) FT_TRACE_DEF( t1gload ) FT_TRACE_DEF( t1hint ) @@ -114,6 +119,7 @@ FT_TRACE_DEF( otvgdef ) FT_TRACE_DEF( otvgpos ) FT_TRACE_DEF( otvgsub ) FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) /* TrueTypeGX/AAT validation components */ FT_TRACE_DEF( gxvmodule ) diff --git a/lib/3rdparty/freetype/include/freetype/internal/internal.h b/lib/3rdparty/freetype/include/freetype/internal/internal.h index 27d5dc585d3..f500a651c27 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/internal.h +++ b/lib/3rdparty/freetype/include/freetype/internal/internal.h @@ -25,6 +25,7 @@ #define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_PIC_H <freetype/internal/ftpic.h> #define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> diff --git a/lib/3rdparty/freetype/include/freetype/internal/psaux.h b/lib/3rdparty/freetype/include/freetype/internal/psaux.h index 4baf7a094a8..a96e0dfa865 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/psaux.h +++ b/lib/3rdparty/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -197,6 +197,7 @@ FT_BEGIN_HEADER { T1_FIELD_LOCATION_CID_INFO, T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_EXTRA, T1_FIELD_LOCATION_FONT_INFO, T1_FIELD_LOCATION_PRIVATE, T1_FIELD_LOCATION_BBOX, @@ -227,7 +228,11 @@ FT_BEGIN_HEADER FT_UInt array_max; /* maximal number of elements for */ /* array */ FT_UInt count_offset; /* offset of element count for */ - /* arrays */ + /* arrays; must not be zero if in */ + /* use -- in other words, a */ + /* `num_FOO' element must not */ + /* start the used structure if we */ + /* parse a `FOO' array */ FT_UInt dict; /* where we expect it */ } T1_FieldRec; @@ -355,7 +360,7 @@ FT_BEGIN_HEADER FT_Error (*to_bytes)( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); @@ -528,13 +533,6 @@ FT_BEGIN_HEADER /* */ /* max_contours :: Maximal number of contours in builder outline. */ /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scaling value (FUnits to */ - /* sub-pixels). */ - /* */ - /* scale_y :: The vertical scaling value (FUnits to sub-pixels). */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -567,11 +565,6 @@ FT_BEGIN_HEADER FT_Outline* base; FT_Outline* current; - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - FT_Pos pos_x; FT_Pos pos_y; @@ -582,7 +575,6 @@ FT_BEGIN_HEADER T1_ParseState parse_state; FT_Bool load_points; FT_Bool no_recurse; - FT_Bool shift; FT_Bool metrics_only; @@ -697,9 +689,11 @@ FT_BEGIN_HEADER T1_Decoder_Callback parse_callback; T1_Decoder_FuncsRec funcs; - FT_Int* buildchar; + FT_Long* buildchar; FT_UInt len_buildchar; + FT_Bool seac; + } T1_DecoderRec; @@ -761,7 +755,7 @@ FT_BEGIN_HEADER FT_Int (*get_index)( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ); void* user_data; diff --git a/lib/3rdparty/freetype/include/freetype/internal/pshints.h b/lib/3rdparty/freetype/include/freetype/internal/pshints.h index 48452c0cf3e..0c357651be4 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/pshints.h +++ b/lib/3rdparty/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ /* */ -/* Copyright 2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -157,7 +157,8 @@ FT_BEGIN_HEADER * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). * * coords :: - * Array of 2 integers, used as (position,length) stem descriptor. + * Array of 2 coordinates in 16.16 format, used as (position,length) + * stem descriptor. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -175,9 +176,9 @@ FT_BEGIN_HEADER * */ typedef void - (*T1_Hints_SetStemFunc)( T1_Hints hints, - FT_UInt dimension, - FT_Long* coords ); + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); /************************************************************************* @@ -197,8 +198,8 @@ FT_BEGIN_HEADER * 0 for horizontal stems, 1 for vertical ones. * * coords :: - * An array of 6 integers, holding 3 (position,length) pairs for the - * counter-controlled stems. + * An array of 6 values in 16.16 format, holding 3 (position,length) + * pairs for the counter-controlled stems. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -209,9 +210,9 @@ FT_BEGIN_HEADER * */ typedef void - (*T1_Hints_SetStem3Func)( T1_Hints hints, - FT_UInt dimension, - FT_Long* coords ); + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Fixed* coords ); /************************************************************************* @@ -446,7 +447,7 @@ FT_BEGIN_HEADER * The number of stems. * * coords :: - * An array of `count' (position,length) pairs. + * An array of `count' (position,length) pairs in 16.16 format. * * @note: * Use vertical coordinates (y) for horizontal stems (dim=0). Use @@ -678,6 +679,30 @@ FT_BEGIN_HEADER typedef PSHinter_Interface* PSHinter_Service; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \ + get_t1_funcs_, get_t2_funcs_) \ + static const PSHinter_Interface class_ = \ + { \ + get_globals_funcs_, get_t1_funcs_, get_t2_funcs_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_, \ + get_t1_funcs_, get_t2_funcs_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + PSHinter_Interface* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_globals_funcs = get_globals_funcs_; \ + clazz->get_t1_funcs = get_t1_funcs_; \ + clazz->get_t2_funcs = get_t2_funcs_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h b/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h index 0f7fc6115d6..9264239146b 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svbdf.h @@ -45,6 +45,26 @@ FT_BEGIN_HEADER FT_BDF_GetPropertyFunc get_property; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + static const FT_Service_BDFRec class_ = \ + { \ + get_charset_id_, get_property_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \ + void \ + FT_Init_Class_##class_( FT_Service_BDFRec* clazz ) \ + { \ + clazz->get_charset_id = get_charset_id_; \ + clazz->get_property = get_property_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h b/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h new file mode 100644 index 00000000000..9b874b5e725 --- /dev/null +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svcid.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* svcid.h */ +/* */ +/* The FreeType CID font services (specification). */ +/* */ +/* Copyright 2007, 2009 by Derek Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVCID_H__ +#define __SVCID_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CID "CID" + + typedef FT_Error + (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ); + typedef FT_Error + (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, + FT_Bool *is_cid ); + typedef FT_Error + (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + FT_DEFINE_SERVICE( CID ) + { + FT_CID_GetRegistryOrderingSupplementFunc get_ros; + FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; + FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; + }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + static const FT_Service_CIDRec class_ = \ + { \ + get_ros_, get_is_cid_, get_cid_from_glyph_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_, \ + get_is_cid_, get_cid_from_glyph_index_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_CIDRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ros = get_ros_; \ + clazz->get_is_cid = get_is_cid_; \ + clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + + +#endif /* __SVCID_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h b/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h index e5e56b253c1..d66a41d5ae3 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svgldict.h @@ -51,6 +51,28 @@ FT_BEGIN_HEADER FT_GlyphDict_NameIndexFunc name_index; /* optional */ }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + static const FT_Service_GlyphDictRec class_ = \ + { \ + get_name_, name_index_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_GlyphDictRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_name = get_name_; \ + clazz->name_index = name_index_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h b/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h index 8a99ec4b1a7..66e1da22f1a 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svmm.h @@ -68,6 +68,31 @@ FT_BEGIN_HEADER FT_Set_Var_Design_Func set_var_design; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_, \ + set_mm_blend_, get_mm_var_, set_var_design_) \ + void \ + FT_Init_Class_##class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h b/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h index 282da68d13e..106c54f8530 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svpostnm.h @@ -46,6 +46,27 @@ FT_BEGIN_HEADER FT_PsName_GetFunc get_ps_font_name; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + static const FT_Service_PsFontNameRec class_ = \ + { \ + get_ps_font_name_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsFontNameRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_ps_font_name = get_ps_font_name_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h b/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h index c4e25ed635f..961030cc391 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svpscmap.h @@ -98,7 +98,7 @@ FT_BEGIN_HEADER (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, FT_UInt32 unicode ); - typedef FT_ULong + typedef FT_UInt32 (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, FT_UInt32 *unicode ); @@ -117,6 +117,41 @@ FT_BEGIN_HEADER const unsigned short* adobe_expert_encoding; }; + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + static const FT_Service_PsCMapsRec class_ = \ + { \ + unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \ + unicodes_char_index_, unicodes_char_next_, macintosh_name_, \ + adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->unicode_value = unicode_value_; \ + clazz->unicodes_init = unicodes_init_; \ + clazz->unicodes_char_index = unicodes_char_index_; \ + clazz->unicodes_char_next = unicodes_char_next_; \ + clazz->macintosh_name = macintosh_name_; \ + clazz->adobe_std_strings = adobe_std_strings_; \ + clazz->adobe_std_encoding = adobe_std_encoding_; \ + clazz->adobe_expert_encoding = adobe_expert_encoding_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h b/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h index 63f5db9c19a..91ba91e5dc0 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript info service (specification). */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003, 2004, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,6 +33,10 @@ FT_BEGIN_HEADER (*PS_GetFontInfoFunc)( FT_Face face, PS_FontInfoRec* afont_info ); + typedef FT_Error + (*PS_GetFontExtraFunc)( FT_Face face, + PS_FontExtraRec* afont_extra ); + typedef FT_Int (*PS_HasGlyphNamesFunc)( FT_Face face ); @@ -44,10 +48,38 @@ FT_BEGIN_HEADER FT_DEFINE_SERVICE( PsInfo ) { PS_GetFontInfoFunc ps_get_font_info; + PS_GetFontExtraFunc ps_get_font_extra; PS_HasGlyphNamesFunc ps_has_glyph_names; PS_GetFontPrivateFunc ps_get_font_private; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + static const FT_Service_PsInfoRec class_ = \ + { \ + get_font_info_, ps_get_font_extra_, has_glyph_names_, \ + get_font_private_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_, \ + ps_get_font_extra_, has_glyph_names_, get_font_private_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_PsInfoRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->ps_get_font_info = get_font_info_; \ + clazz->ps_get_font_extra = ps_get_font_extra_; \ + clazz->ps_has_glyph_names = has_glyph_names_; \ + clazz->ps_get_font_private = get_font_private_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h b/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h index b4a85d97ec7..30bb1620fe1 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svsfnt.h @@ -58,6 +58,7 @@ FT_BEGIN_HEADER (*FT_SFNT_TableInfoFunc)( FT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ); @@ -68,6 +69,27 @@ FT_BEGIN_HEADER FT_SFNT_TableInfoFunc table_info; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + static const FT_Service_SFNT_TableRec class_ = \ + { \ + load_, get_, info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \ + void \ + FT_Init_Class_##class_( FT_Service_SFNT_TableRec* clazz ) \ + { \ + clazz->load_table = load_; \ + clazz->get_table = get_; \ + clazz->table_info = info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h b/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h index 1e02d15506d..8af00351d9d 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svttcmap.h @@ -1,13 +1,13 @@ /***************************************************************************/ /* */ -/* svsttcmap.h */ +/* svttcmap.h */ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ /* Copyright 2003 by */ /* Masatake YAMATO, Redhat K.K. */ /* */ -/* Copyright 2003 by */ +/* Copyright 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,6 +49,13 @@ FT_BEGIN_HEADER /* The language ID used in Mac fonts. Definitions of values are in */ /* freetype/ttnameid.h. */ /* */ + /* format :: */ + /* The cmap format. OpenType 1.5 defines the formats 0 (byte */ + /* encoding table), 2~(high-byte mapping through table), 4~(segment */ + /* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */ + /* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */ + /* coverage), and 14 (Unicode Variation Sequences). */ + /* */ typedef struct TT_CMapInfo_ { FT_ULong language; @@ -67,6 +74,27 @@ FT_BEGIN_HEADER TT_CMap_Info_GetFunc get_cmap_info; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + static const FT_Service_TTCMapsRec class_ = \ + { \ + get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( FT_Library library, \ + FT_Service_TTCMapsRec* clazz) \ + { \ + FT_UNUSED(library); \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h b/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h index e57d484b7e2..ab2dc9a9fe9 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h +++ b/lib/3rdparty/freetype/include/freetype/internal/services/svttglyf.h @@ -37,6 +37,25 @@ FT_BEGIN_HEADER TT_Glyf_GetLocationFunc get_location; }; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + static const FT_Service_TTGlyfRec class_ = \ + { \ + get_location_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ ) \ + void \ + FT_Init_Class_##class_( FT_Service_TTGlyfRec* clazz ) \ + { \ + clazz->get_location = get_location_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/sfnt.h b/lib/3rdparty/freetype/include/freetype/internal/sfnt.h index 7e8f6847c98..6326debd00c 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/sfnt.h +++ b/lib/3rdparty/freetype/include/freetype/internal/sfnt.h @@ -753,6 +753,141 @@ FT_BEGIN_HEADER /* transitional */ typedef SFNT_Interface* SFNT_Service; +#ifndef FT_CONFIG_OPTION_PIC + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \ + a, +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) +#endif +#define FT_INTERNAL(a) \ + a, + +#define FT_DEFINE_SFNT_INTERFACE(class_, \ + goto_table_, init_face_, load_face_, done_face_, get_interface_, \ + load_any_, load_sfnt_header_, load_directory_, load_head_, \ + load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \ + load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \ + load_kern_, load_gasp_, load_pclt_, load_bhed_, \ + set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \ + load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \ + get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \ + get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \ + set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \ + static const SFNT_Interface class_ = \ + { \ + FT_INTERNAL(goto_table_) \ + FT_INTERNAL(init_face_) \ + FT_INTERNAL(load_face_) \ + FT_INTERNAL(done_face_) \ + FT_INTERNAL(get_interface_) \ + FT_INTERNAL(load_any_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \ + FT_INTERNAL(load_head_) \ + FT_INTERNAL(load_hhea_) \ + FT_INTERNAL(load_cmap_) \ + FT_INTERNAL(load_maxp_) \ + FT_INTERNAL(load_os2_) \ + FT_INTERNAL(load_post_) \ + FT_INTERNAL(load_name_) \ + FT_INTERNAL(free_name_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \ + FT_INTERNAL(load_kern_) \ + FT_INTERNAL(load_gasp_) \ + FT_INTERNAL(load_pclt_) \ + FT_INTERNAL(load_bhed_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \ + FT_INTERNAL(load_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \ + FT_INTERNAL(get_psname_) \ + FT_INTERNAL(free_psnames_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \ + FT_INTERNAL(get_kerning_) \ + FT_INTERNAL(load_font_dir_) \ + FT_INTERNAL(load_hmtx_) \ + FT_INTERNAL(load_eblc_) \ + FT_INTERNAL(free_eblc_) \ + FT_INTERNAL(set_sbit_strike_) \ + FT_INTERNAL(load_strike_metrics_) \ + FT_INTERNAL(get_metrics_) \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \ + clazz->a = a_; +#else + #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) +#endif +#define FT_INTERNAL(a, a_) \ + clazz->a = a_; + +#define FT_DEFINE_SFNT_INTERFACE(class_, \ + goto_table_, init_face_, load_face_, done_face_, get_interface_, \ + load_any_, load_sfnt_header_, load_directory_, load_head_, \ + load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_, \ + load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_, \ + load_kern_, load_gasp_, load_pclt_, load_bhed_, \ + set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_, \ + load_sbit_metrics_, load_sbit_image_, free_sbits_stub_, \ + get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_, \ + get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_, \ + set_sbit_strike_, load_strike_metrics_, get_metrics_ ) \ + void \ + FT_Init_Class_##class_( FT_Library library, SFNT_Interface* clazz ) \ + { \ + FT_UNUSED(library); \ + FT_INTERNAL(goto_table,goto_table_) \ + FT_INTERNAL(init_face,init_face_) \ + FT_INTERNAL(load_face,load_face_) \ + FT_INTERNAL(done_face,done_face_) \ + FT_INTERNAL(get_interface,get_interface_) \ + FT_INTERNAL(load_any,load_any_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \ + FT_INTERNAL(load_head,load_head_) \ + FT_INTERNAL(load_hhea,load_hhea_) \ + FT_INTERNAL(load_cmap,load_cmap_) \ + FT_INTERNAL(load_maxp,load_maxp_) \ + FT_INTERNAL(load_os2,load_os2_) \ + FT_INTERNAL(load_post,load_post_) \ + FT_INTERNAL(load_name,load_name_) \ + FT_INTERNAL(free_name,free_name_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \ + FT_INTERNAL(load_kern,load_kern_) \ + FT_INTERNAL(load_gasp,load_gasp_) \ + FT_INTERNAL(load_pclt,load_pclt_) \ + FT_INTERNAL(load_bhed,load_bhed_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \ + FT_INTERNAL(load_sbit_image,load_sbit_image_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \ + FT_INTERNAL(get_psname,get_psname_) \ + FT_INTERNAL(free_psnames,free_psnames_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \ + FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \ + FT_INTERNAL(get_kerning,get_kerning_) \ + FT_INTERNAL(load_font_dir,load_font_dir_) \ + FT_INTERNAL(load_hmtx,load_hmtx_) \ + FT_INTERNAL(load_eblc,load_eblc_) \ + FT_INTERNAL(free_eblc,free_eblc_) \ + FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \ + FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \ + FT_INTERNAL(get_metrics,get_metrics_) \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/internal/t1types.h b/lib/3rdparty/freetype/include/freetype/internal/t1types.h index 047c6d59df0..5f730637b5b 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/t1types.h +++ b/lib/3rdparty/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,9 @@ FT_BEGIN_HEADER /* */ /* code_first :: The lowest valid character code in the encoding. */ /* */ - /* code_last :: The highest valid character code in the encoding. */ + /* code_last :: The highest valid character code in the encoding */ + /* + 1. When equal to code_first there are no valid */ + /* character codes. */ /* */ /* char_index :: An array of corresponding glyph indices. */ /* */ @@ -87,11 +89,24 @@ FT_BEGIN_HEADER } T1_EncodingType; + /* used to hold extra data of PS_FontInfoRec that + * cannot be stored in the publicly defined structure. + * + * Note these can't be blended with multiple-masters. + */ + typedef struct PS_FontExtraRec_ + { + FT_UShort fs_type; + + } PS_FontExtraRec; + + typedef struct T1_FontRec_ { - PS_FontInfoRec font_info; /* font info dictionary */ - PS_PrivateRec private_dict; /* private dictionary */ - FT_String* font_name; /* top-level dictionary */ + PS_FontInfoRec font_info; /* font info dictionary */ + PS_FontExtraRec font_extra; /* font info extra fields */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ T1_EncodingType encoding_type; T1_EncodingRec encoding; @@ -217,7 +232,7 @@ FT_BEGIN_HEADER /* undocumented, optional: has the same meaning as len_buildchar */ /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ FT_UInt len_buildchar; - FT_Int* buildchar; + FT_Long* buildchar; /* since version 2.1 - interface to PostScript hinter */ const void* pshinter; @@ -231,7 +246,10 @@ FT_BEGIN_HEADER void* psnames; void* psaux; CID_FaceInfoRec cid; + PS_FontExtraRec font_extra; +#if 0 void* afm_data; +#endif CID_Subrs subrs; /* since version 2.1 - interface to PostScript hinter */ diff --git a/lib/3rdparty/freetype/include/freetype/internal/tttypes.h b/lib/3rdparty/freetype/include/freetype/internal/tttypes.h index dfbb6a1ea0b..acbb863b0f1 100644 --- a/lib/3rdparty/freetype/include/freetype/internal/tttypes.h +++ b/lib/3rdparty/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -586,7 +586,7 @@ FT_BEGIN_HEADER /* table_offset :: The offset of the index table in the `EBLC' */ /* table. Only used during strike loading. */ /* */ - typedef struct TT_SBit_RangeRec + typedef struct TT_SBit_RangeRec_ { FT_UShort first_glyph; FT_UShort last_glyph; @@ -902,7 +902,7 @@ FT_BEGIN_HEADER FT_Byte* table; FT_Byte* table_end; FT_Byte* strings; - FT_UInt32 strings_size; + FT_ULong strings_size; FT_UInt num_strikes; FT_Bool loaded; @@ -1401,7 +1401,7 @@ FT_BEGIN_HEADER FT_Byte* vert_metrics; FT_ULong vert_metrics_size; - FT_UInt num_locations; + FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ FT_Byte* glyph_locations; FT_Byte* hdmx_table; diff --git a/lib/3rdparty/freetype/include/freetype/t1tables.h b/lib/3rdparty/freetype/include/freetype/t1tables.h index 250629d2522..5e2a3934cee 100644 --- a/lib/3rdparty/freetype/include/freetype/t1tables.h +++ b/lib/3rdparty/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -43,7 +43,7 @@ FT_BEGIN_HEADER /* Type 1 Tables */ /* */ /* <Abstract> */ - /* Type 1 (PostScript) specific font tables. */ + /* Type~1 (PostScript) specific font tables. */ /* */ /* <Description> */ /* This section contains the definition of Type 1-specific tables, */ @@ -62,11 +62,11 @@ FT_BEGIN_HEADER /* PS_FontInfoRec */ /* */ /* <Description> */ - /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ /* FontInfo dictionary. */ /* */ - typedef struct PS_FontInfoRec + typedef struct PS_FontInfoRec_ { FT_String* version; FT_String* notice; @@ -78,7 +78,18 @@ FT_BEGIN_HEADER FT_Short underline_position; FT_UShort underline_thickness; - } PS_FontInfoRec, *PS_FontInfo; + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; /*************************************************************************/ @@ -100,9 +111,9 @@ FT_BEGIN_HEADER /* PS_PrivateRec */ /* */ /* <Description> */ - /* A structure used to model a Type1/Type2 private dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own Private */ - /* dictionary. */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ /* */ typedef struct PS_PrivateRec_ { @@ -142,7 +153,18 @@ FT_BEGIN_HEADER FT_Short min_feature[2]; - } PS_PrivateRec, *PS_Private; + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; /*************************************************************************/ @@ -168,7 +190,7 @@ FT_BEGIN_HEADER /* given blend dictionary (font info or private). Used to support */ /* Multiple Masters fonts. */ /* */ - typedef enum + typedef enum T1_Blend_Flags_ { /*# required fields in a FontInfo blend dictionary */ T1_BLEND_UNDERLINE_POSITION = 0, @@ -272,6 +294,14 @@ FT_BEGIN_HEADER typedef PS_BlendRec T1_Blend; + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ typedef struct CID_FaceDictRec_ { PS_PrivateRec private_dict; @@ -290,7 +320,20 @@ FT_BEGIN_HEADER FT_ULong subrmap_offset; FT_Int sd_bytes; - } CID_FaceDictRec, *CID_FaceDict; + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + /* */ /* backwards-compatible definition */ @@ -332,7 +375,18 @@ FT_BEGIN_HEADER FT_ULong data_offset; - } CID_FaceInfoRec, *CID_FaceInfo; + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; /*************************************************************************/ @@ -347,99 +401,99 @@ FT_BEGIN_HEADER /* */ typedef CID_FaceInfoRec CID_Info; - /* */ - - /************************************************************************ - * - * @function: - * FT_Has_PS_Glyph_Names - * - * @description: - * Return true if a given face provides reliable Postscript glyph - * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, - * except that certain fonts (mostly TrueType) contain incorrect - * glyph name tables. - * - * When this function returns true, the caller is sure that the glyph - * names returned by @FT_Get_Glyph_Name are reliable. - * - * @input: - * face :: - * face handle - * - * @return: - * Boolean. True if glyph names are reliable. - */ + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ FT_EXPORT( FT_Int ) FT_Has_PS_Glyph_Names( FT_Face face ); - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Info - * - * @description: - * Retrieve the @PS_FontInfoRec structure corresponding to a given - * Postscript font. - * - * @input: - * face :: - * Postscript face handle. - * - * @output: - * afont_info :: - * Output font info structure pointer. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. - * - * If the font's format is not Postscript-based, this function will - * return the `FT_Err_Invalid_Argument' error code. - */ + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ FT_EXPORT( FT_Error ) - FT_Get_PS_Font_Info( FT_Face face, - PS_FontInfoRec *afont_info ); + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); - /************************************************************************ - * - * @function: - * FT_Get_PS_Font_Private - * - * @description: - * Retrieve the @PS_PrivateRec structure corresponding to a given - * Postscript font. - * - * @input: - * face :: - * Postscript face handle. - * - * @output: - * afont_private :: - * Output private dictionary structure pointer. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * The string pointers within the font info structure are owned by - * the face and don't need to be freed by the caller. - * - * If the font's format is not Postscript-based, this function will - * return the `FT_Err_Invalid_Argument' error code. - */ + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the @PS_PrivateRec structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ FT_EXPORT( FT_Error ) - FT_Get_PS_Font_Private( FT_Face face, - PS_PrivateRec *afont_private ); - - /* */ + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + /* */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/include/freetype/ttnameid.h b/lib/3rdparty/freetype/include/freetype/ttnameid.h index b9acbdad119..cbeac78db1e 100644 --- a/lib/3rdparty/freetype/include/freetype/ttnameid.h +++ b/lib/3rdparty/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,13 @@ FT_BEGIN_HEADER + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + /*************************************************************************/ /* */ /* Possible values for the `platform' identifier code in the name */ @@ -108,13 +115,18 @@ FT_BEGIN_HEADER * * TT_APPLE_ID_UNICODE_32 :: * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. */ -#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ -#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ -#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ -#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ -#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ /*********************************************************************** @@ -290,6 +302,8 @@ FT_BEGIN_HEADER * Adobe expert encoding. * TT_ADOBE_ID_CUSTOM :: * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. */ #define TT_ADOBE_ID_STANDARD 0 @@ -821,16 +835,18 @@ FT_BEGIN_HEADER /* This is new in OpenType 1.3 */ #define TT_NAME_ID_CID_FINDFONT_NAME 20 + /* This is new in OpenType 1.5 */ +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + /*************************************************************************/ /* */ /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ /* */ - /* Updated 02-Jul-2000. */ + /* Updated 08-Nov-2008. */ /* */ - /* General Scripts Area */ - /* Bit 0 Basic Latin */ #define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ /* Bit 1 C1 Controls and Latin-1 Supplement */ @@ -839,27 +855,44 @@ FT_BEGIN_HEADER #define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ /* Bit 3 Latin Extended-B */ #define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ - /* Bit 4 IPA Extensions */ + /* Bit 4 IPA Extensions */ + /* Phonetic Extensions */ + /* Phonetic Extensions Supplement */ #define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* U+1D00-U+1D7F */ + /* U+1D80-U+1DBF */ /* Bit 5 Spacing Modifier Letters */ + /* Modifier Tone Letters */ #define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ - /* Bit 6 Combining Diacritical Marks */ + /* U+A700-U+A71F */ + /* Bit 6 Combining Diacritical Marks */ + /* Combining Diacritical Marks Supplement */ #define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* U+1DC0-U+1DFF */ /* Bit 7 Greek and Coptic */ #define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ - /* Bit 8 is reserved (was: Greek Symbols and Coptic) */ - /* Bit 9 Cyrillic + */ - /* Cyrillic Supplementary */ + /* Bit 8 Coptic */ +#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ + /* Bit 9 Cyrillic */ + /* Cyrillic Supplement */ + /* Cyrillic Extended-A */ + /* Cyrillic Extended-B */ #define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ /* U+0500-U+052F */ + /* U+2DE0-U+2DFF */ + /* U+A640-U+A69F */ /* Bit 10 Armenian */ #define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ /* Bit 11 Hebrew */ #define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ - /* Bit 12 is reserved (was: Hebrew Extended) */ - /* Bit 13 Arabic */ + /* Bit 12 Vai */ +#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ + /* Bit 13 Arabic */ + /* Arabic Supplement */ #define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ - /* Bit 14 is reserved (was: Arabic Extended) */ + /* U+0750-U+077F */ + /* Bit 14 NKo */ +#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ /* Bit 15 Devanagari */ #define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ /* Bit 16 Bengali */ @@ -882,20 +915,26 @@ FT_BEGIN_HEADER #define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ /* Bit 25 Lao */ #define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ - /* Bit 26 Georgian */ + /* Bit 26 Georgian */ + /* Georgian Supplement */ #define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ - /* Bit 27 is reserved (was Georgian Extended) */ + /* U+2D00-U+2D2F */ + /* Bit 27 Balinese */ +#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ /* Bit 28 Hangul Jamo */ #define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ /* Bit 29 Latin Extended Additional */ + /* Latin Extended-C */ + /* Latin Extended-D */ #define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* U+2C60-U+2C7F */ + /* U+A720-U+A7FF */ /* Bit 30 Greek Extended */ #define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ - - /* Symbols Area */ - - /* Bit 31 General Punctuation */ + /* Bit 31 General Punctuation */ + /* Supplemental Punctuation */ #define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* U+2E00-U+2E7F */ /* Bit 32 Superscripts And Subscripts */ #define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ /* Bit 33 Currency Symbols */ @@ -906,16 +945,18 @@ FT_BEGIN_HEADER #define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ /* Bit 36 Number Forms */ #define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ - /* Bit 37 Arrows + */ - /* Supplemental Arrows-A + */ - /* Supplemental Arrows-B */ + /* Bit 37 Arrows */ + /* Supplemental Arrows-A */ + /* Supplemental Arrows-B */ + /* Miscellaneous Symbols and Arrows */ #define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ /* U+27F0-U+27FF */ /* U+2900-U+297F */ - /* Bit 38 Mathematical Operators + */ - /* Supplemental Mathematical Operators + */ - /* Miscellaneous Mathematical Symbols-A + */ - /* Miscellaneous Mathematical Symbols-B */ + /* U+2B00-U+2BFF */ + /* Bit 38 Mathematical Operators */ + /* Supplemental Mathematical Operators */ + /* Miscellaneous Mathematical Symbols-A */ + /* Miscellaneous Mathematical Symbols-B */ #define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ /* U+2A00-U+2AFF */ /* U+27C0-U+27EF */ @@ -938,60 +979,53 @@ FT_BEGIN_HEADER #define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ /* Bit 47 Dingbats */ #define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ - - /* CJK Phonetics and Symbols Area */ - /* Bit 48 CJK Symbols and Punctuation */ #define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ /* Bit 49 Hiragana */ #define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ - /* Bit 50 Katakana + */ - /* Katakana Phonetic Extensions */ + /* Bit 50 Katakana */ + /* Katakana Phonetic Extensions */ #define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ /* U+31F0-U+31FF */ - /* Bit 51 Bopomofo + */ - /* Bopomofo Extended */ + /* Bit 51 Bopomofo */ + /* Bopomofo Extended */ #define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ /* U+31A0-U+31BF */ /* Bit 52 Hangul Compatibility Jamo */ #define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ - /* Bit 53 Kanbun */ -#define TT_UCR_CJK_MISC (1L << 21) /* U+3190-U+319F */ -#define TT_UCR_KANBUN TT_UCR_CJK_MISC + /* Bit 53 Phags-Pa */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ +#define TT_UCR_PHAGSPA /* Bit 54 Enclosed CJK Letters and Months */ #define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ /* Bit 55 CJK Compatibility */ #define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ - - /* Hangul Syllables Area */ - - /* Bit 56 Hangul */ + /* Bit 56 Hangul Syllables */ #define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ - - /* Surrogates Area */ - - /* Bit 57 High Surrogates + */ - /* High Private Use Surrogates + */ - /* Low Surrogates */ + /* Bit 57 High Surrogates */ + /* High Private Use Surrogates */ + /* Low Surrogates */ + /* */ + /* According to OpenType specs v.1.3+, */ + /* setting bit 57 implies that there is */ + /* at least one codepoint beyond the */ + /* Basic Multilingual Plane that is */ + /* supported by this font. So it really */ + /* means >= U+10000 */ #define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ /* U+DB80-U+DBFF */ /* U+DC00-U+DFFF */ - /* According to OpenType specs v.1.3+, setting bit 57 implies that there */ - /* is at least one codepoint beyond the Basic Multilingual Plane that is */ - /* supported by this font. So it really means: >= U+10000 */ - - /* Bit 58 is reserved for Unicode SubRanges */ - - /* CJK Ideographs Area */ - - /* Bit 59 CJK Unified Ideographs + */ - /* CJK Radicals Supplement + */ - /* Kangxi Radicals + */ - /* Ideographic Description Characters + */ - /* CJK Unified Ideographs Extension A */ - /* CJK Unified Ideographs Extension A + */ - /* CJK Unified Ideographs Extension B + */ - /* Kanbun */ +#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES + /* Bit 58 Phoenician */ +#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ + /* Bit 59 CJK Unified Ideographs */ + /* CJK Radicals Supplement */ + /* Kangxi Radicals */ + /* Ideographic Description Characters */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension B */ + /* Kanbun */ #define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ /* U+2E80-U+2EFF */ /* U+2F00-U+2FDF */ @@ -999,17 +1033,13 @@ FT_BEGIN_HEADER /* U+3400-U+4DB5 */ /*U+20000-U+2A6DF*/ /* U+3190-U+319F */ - - /* Private Use Area */ - /* Bit 60 Private Use */ #define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ - - /* Compatibility Area and Specials */ - - /* Bit 61 CJK Compatibility Ideographs + */ - /* CJK Compatibility Ideographs Supplement */ -#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+F900-U+FAFF */ + /* Bit 61 CJK Strokes */ + /* CJK Compatibility Ideographs */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ + /* U+F900-U+FAFF */ /*U+2F800-U+2FA1F*/ /* Bit 62 Alphabetic Presentation Forms */ #define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ @@ -1017,8 +1047,10 @@ FT_BEGIN_HEADER #define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ /* Bit 64 Combining Half Marks */ #define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ - /* Bit 65 CJK Compatibility Forms */ -#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE30-U+FE4F */ + /* Bit 65 Vertical forms */ + /* CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ + /* U+FE30-U+FE4F */ /* Bit 66 Small Form Variants */ #define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ /* Bit 67 Arabic Presentation Forms-B */ @@ -1037,8 +1069,12 @@ FT_BEGIN_HEADER #define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ /* Bit 74 Myanmar */ #define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ - /* Bit 75 Ethiopic */ + /* Bit 75 Ethiopic */ + /* Ethiopic Supplement */ + /* Ethiopic Extended */ #define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* U+1380-U+139F */ + /* U+2D80-U+2DDF */ /* Bit 76 Cherokee */ #define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ /* Bit 77 Unified Canadian Aboriginal Syllabics */ @@ -1047,20 +1083,22 @@ FT_BEGIN_HEADER #define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ /* Bit 79 Runic */ #define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ - /* Bit 80 Khmer */ + /* Bit 80 Khmer */ + /* Khmer Symbols */ #define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* U+19E0-U+19FF */ /* Bit 81 Mongolian */ #define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ /* Bit 82 Braille Patterns */ #define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ - /* Bit 83 Yi Syllables + */ - /* Yi Radicals */ + /* Bit 83 Yi Syllables */ + /* Yi Radicals */ #define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ /* U+A490-U+A4CF */ - /* Bit 84 Tagalog + */ - /* Hanunoo + */ - /* Buhid + */ - /* Tagbanwa */ + /* Bit 84 Tagalog */ + /* Hanunoo */ + /* Buhid */ + /* Tagbanwa */ #define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ /* U+1720-U+173F */ /* U+1740-U+175F */ @@ -1071,20 +1109,97 @@ FT_BEGIN_HEADER #define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ /* Bit 87 Deseret */ #define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ - /* Bit 88 Byzantine Musical Symbols + */ - /* Musical Symbols */ + /* Bit 88 Byzantine Musical Symbols */ + /* Musical Symbols */ + /* Ancient Greek Musical Notation */ #define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ /*U+1D100-U+1D1FF*/ + /*U+1D200-U+1D24F*/ /* Bit 89 Mathematical Alphanumeric Symbols */ #define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ - /* Bit 90 Private Use (plane 15) + */ - /* Private Use (plane 16) */ + /* Bit 90 Private Use (plane 15) */ + /* Private Use (plane 16) */ #define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ /*U+100000-U+10FFFD*/ - /* Bit 91 Variation Selectors */ + /* Bit 91 Variation Selectors */ + /* Variation Selectors Supplement */ #define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /*U+E0100-U+E01EF*/ /* Bit 92 Tags */ #define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + /* Bit 93 Limbu */ +#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ + /* Bit 94 Tai Le */ +#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ + /* Bit 95 New Tai Lue */ +#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + /* Bit 96 Buginese */ +#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ + /* Bit 97 Glagolitic */ +#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ + /* Bit 98 Tifinagh */ +#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ + /* Bit 99 Yijing Hexagram Symbols */ +#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ + /* Bit 100 Syloti Nagri */ +#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ + /* Bit 101 Linear B Syllabary */ + /* Linear B Ideograms */ + /* Aegean Numbers */ +#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ + /*U+10080-U+100FF*/ + /*U+10100-U+1013F*/ + /* Bit 102 Ancient Greek Numbers */ +#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ + /* Bit 103 Ugaritic */ +#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ + /* Bit 104 Old Persian */ +#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ + /* Bit 105 Shavian */ +#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ + /* Bit 106 Osmanya */ +#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ + /* Bit 107 Cypriot Syllabary */ +#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ + /* Bit 108 Kharoshthi */ +#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ + /* Bit 109 Tai Xuan Jing Symbols */ +#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ + /* Bit 110 Cuneiform */ + /* Cuneiform Numbers and Punctuation */ +#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ + /*U+12400-U+1247F*/ + /* Bit 111 Counting Rod Numerals */ +#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ + /* Bit 112 Sundanese */ +#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ + /* Bit 113 Lepcha */ +#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ + /* Bit 114 Ol Chiki */ +#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ + /* Bit 115 Saurashtra */ +#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ + /* Bit 116 Kayah Li */ +#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ + /* Bit 117 Rejang */ +#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ + /* Bit 118 Cham */ +#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ + /* Bit 119 Ancient Symbols */ +#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ + /* Bit 120 Phaistos Disc */ +#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ + /* Bit 121 Carian */ + /* Lycian */ + /* Lydian */ +#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ + /*U+10280-U+1029F*/ + /*U+10920-U+1093F*/ + /* Bit 122 Domino Tiles */ + /* Mahjong Tiles */ +#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ + /*U+1F000-U+1F02F*/ + /* Bit 123-127 Reserved for process-internal usage */ /*************************************************************************/ @@ -1103,7 +1218,7 @@ FT_BEGIN_HEADER /* */ /* Here some alias #defines in order to be clearer. */ /* */ - /* These are not always #defined to stay within the 31 character limit */ + /* These are not always #defined to stay within the 31~character limit */ /* which some compilers have. */ /* */ /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ diff --git a/lib/3rdparty/freetype/include/freetype/tttables.h b/lib/3rdparty/freetype/include/freetype/tttables.h index 43eca2e2580..c12b1726896 100644 --- a/lib/3rdparty/freetype/include/freetype/tttables.h +++ b/lib/3rdparty/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -156,9 +156,9 @@ FT_BEGIN_HEADER /* caret_Slope_Run :: The run coefficient of the cursor's */ /* slope. */ /* */ - /* Reserved :: 10 reserved bytes. */ + /* Reserved :: 8~reserved bytes. */ /* */ - /* metric_Data_Format :: Always 0. */ + /* metric_Data_Format :: Always~0. */ /* */ /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ /* table -- this value can be smaller than */ @@ -281,9 +281,9 @@ FT_BEGIN_HEADER /* This value is `reserved' in vmtx */ /* version 1.0. */ /* */ - /* Reserved :: 8 reserved bytes. */ + /* Reserved :: 8~reserved bytes. */ /* */ - /* metric_Data_Format :: Always 0. */ + /* metric_Data_Format :: Always~0. */ /* */ /* number_Of_HMetrics :: Number of VMetrics entries in the */ /* `vmtx' table -- this value can be */ @@ -406,9 +406,9 @@ FT_BEGIN_HEADER /* TT_Postscript */ /* */ /* <Description> */ - /* A structure used to model a TrueType Postscript table. All fields */ + /* A structure used to model a TrueType PostScript table. All fields */ /* comply to the TrueType specification. This structure does not */ - /* reference the Postscript glyph names, which can be nevertheless */ + /* reference the PostScript glyph names, which can be nevertheless */ /* accessed with the `ttpost' module. */ /* */ typedef struct TT_Postscript_ @@ -555,7 +555,7 @@ FT_BEGIN_HEADER /* An enumeration used to specify the index of an SFNT table. */ /* Used in the @FT_Get_Sfnt_Table API function. */ /* */ - typedef enum + typedef enum FT_Sfnt_Tag_ { ft_sfnt_head = 0, ft_sfnt_maxp = 1, @@ -578,7 +578,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Table */ /* */ /* <Description> */ - /* Returns a pointer to a given SFNT table within a face. */ + /* Return a pointer to a given SFNT table within a face. */ /* */ /* <Input> */ /* face :: A handle to the source. */ @@ -586,7 +586,7 @@ FT_BEGIN_HEADER /* tag :: The index of the SFNT table. */ /* */ /* <Return> */ - /* A type-less pointer to the table. This will be 0 in case of */ + /* A type-less pointer to the table. This will be~0 in case of */ /* error, or if the corresponding table was not found *OR* loaded */ /* from the file. */ /* */ @@ -608,14 +608,14 @@ FT_BEGIN_HEADER * FT_Load_Sfnt_Table * * @description: - * Loads any font table into client memory. + * Load any font table into client memory. * * @input: * face :: * A handle to the source face. * * tag :: - * The four-byte tag of the table to load. Use the value 0 if you want + * The four-byte tag of the table to load. Use the value~0 if you want * to access the whole font file. Otherwise, you can use one of the * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new * one with @FT_MAKE_TAG. @@ -633,18 +633,18 @@ FT_BEGIN_HEADER * If the `length' parameter is NULL, then try to load the whole table. * Return an error code if it fails. * - * Else, if `*length' is 0, exit immediately while returning the + * Else, if `*length' is~0, exit immediately while returning the * table's (or file) full size in it. * * Else the number of bytes to read from the table or file, from the * starting offset. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: * If you need to determine the table's length you should first call this - * function with `*length' set to 0, as in the following example: + * function with `*length' set to~0, as in the following example: * * { * FT_ULong length = 0; @@ -674,7 +674,7 @@ FT_BEGIN_HEADER * FT_Sfnt_Table_Info * * @description: - * Returns information on an SFNT table. + * Return information on an SFNT table. * * @input: * face :: @@ -692,10 +692,10 @@ FT_BEGIN_HEADER * The length of the SFNT table. * * @return: - * FreeType error code. 0 means success. + * FreeType error code. 0~means success. * * @note: - * SFNT tables with length zero are treated as missing by Windows. + * SFNT tables with length zero are treated as missing. * */ FT_EXPORT( FT_Error ) @@ -720,7 +720,7 @@ FT_BEGIN_HEADER /* */ /* <Return> */ /* The language ID of `charmap'. If `charmap' doesn't belong to a */ - /* TrueType/sfnt face, just return 0 as the default value. */ + /* TrueType/sfnt face, just return~0 as the default value. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_CMap_Language_ID( FT_CharMap charmap ); diff --git a/lib/3rdparty/freetype/include/freetype/tttags.h b/lib/3rdparty/freetype/include/freetype/tttags.h index e10244ca7c9..307ce4b6374 100644 --- a/lib/3rdparty/freetype/include/freetype/tttags.h +++ b/lib/3rdparty/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2001, 2004, 2005 by */ +/* Copyright 1996-2001, 2004, 2005, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,6 +41,7 @@ FT_BEGIN_HEADER #define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) #define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) #define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) @@ -49,6 +50,7 @@ FT_BEGIN_HEADER #define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) #define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) #define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) #define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) #define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) #define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) @@ -67,6 +69,8 @@ FT_BEGIN_HEADER #define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) #define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) #define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) #define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) #define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) #define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) @@ -78,14 +82,18 @@ FT_BEGIN_HEADER #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) #define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) #define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) #define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) #define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) #define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) #define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) #define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) #define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) #define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) #define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) +#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) diff --git a/lib/3rdparty/freetype/modules.cfg b/lib/3rdparty/freetype/modules.cfg index 6d8a95eaca6..4047d7f09cf 100644 --- a/lib/3rdparty/freetype/modules.cfg +++ b/lib/3rdparty/freetype/modules.cfg @@ -1,6 +1,6 @@ # modules.cfg # -# Copyright 2005, 2006, 2007 by +# Copyright 2005, 2006, 2007, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -106,7 +106,7 @@ RASTER_MODULES += smooth # FreeType's cache sub-system (quite stable but still in beta -- this means # that its public API is subject to change if necessary). See -# include/freetype/ftcache.h. +# include/freetype/ftcache.h. Needs ftglyph.c. AUX_MODULES += cache # TrueType GX/AAT table validation. Needs ftgxval.c below. @@ -158,37 +158,62 @@ BASE_EXTENSIONS += ftbdf.c # See include/freetype/ftbitmap.h for the API. BASE_EXTENSIONS += ftbitmap.c -# Convenience functions to handle glyphs. +# Access CID font information. +# +# See include/freetype/ftcid.h for the API. +BASE_EXTENSIONS += ftcid.c + +# Access FSType information. Needs fttype1.c. +# +# See include/freetype/freetype.h for the API. +BASE_EXTENSIONS += ftfstype.c + +# Support for GASP table queries. +# +# See include/freetype/ftgasp.h for the API. +BASE_EXTENSIONS += ftgasp.c + +# Convenience functions to handle glyphs. Needs ftbitmap.c. # # See include/freetype/ftglyph.h for the API. BASE_EXTENSIONS += ftglyph.c -# Interface for gxvalid module (which is required). +# Interface for gxvalid module. # # See include/freetype/ftgxval.h for the API. BASE_EXTENSIONS += ftgxval.c +# Support for LCD color filtering of subpixel bitmaps. +# +# See include/freetype/ftlcdfil.h for the API. +BASE_EXTENSIONS += ftlcdfil.c + # Multiple Master font interface. # # See include/freetype/ftmm.h for the API. BASE_EXTENSIONS += ftmm.c -# Interface for otvalid module (which is required). +# Interface for otvalid module. # # See include/freetype/ftotval.h for the API. BASE_EXTENSIONS += ftotval.c +# Support for FT_Face_CheckTrueTypePatents. +# +# See include/freetype/freetype.h for the API. +BASE_EXTENSIONS += ftpatent.c + # Interface for accessing PFR-specific data. Needs PFR font driver. # # See include/freetype/ftpfr.h for the API. BASE_EXTENSIONS += ftpfr.c -# Path stroker. +# Path stroker. Needs ftglyph.c. # # See include/freetype/ftstroke.h for the API. BASE_EXTENSIONS += ftstroke.c -# Support for synthetic embolding and slanting of fonts. +# Support for synthetic embolding and slanting of fonts. Needs ftbitmap.c. # # See include/freetype/ftsynth.h for the API. BASE_EXTENSIONS += ftsynth.c @@ -210,21 +235,6 @@ BASE_EXTENSIONS += ftwinfnt.c # See include/freetype/ftxf86.h for the API. BASE_EXTENSIONS += ftxf86.c -# Support for LCD color filtering of subpixel bitmaps. -# -# See include/freetype/ftlcdfil.h for the API. -BASE_EXTENSIONS += ftlcdfil.c - -# Support for GASP table queries. -# -# See include/freetype/ftgasp.h for the API. -BASE_EXTENSIONS += ftgasp.c - -# Support for FT_Face_CheckTrueTypePatents. -# -# See include/freetype.h for the API. -BASE_EXTENSIONS += ftpatent.c - #### #### The components `ftsystem.c' (for memory allocation and stream I/O #### management) and `ftdebug.c' (for emitting debug messages to the user) diff --git a/lib/3rdparty/freetype/src/autofit/Jamfile b/lib/3rdparty/freetype/src/autofit/Jamfile index acee8bf2cbf..2714765b5b5 100644 --- a/lib/3rdparty/freetype/src/autofit/Jamfile +++ b/lib/3rdparty/freetype/src/autofit/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/autofit Jamfile # -# Copyright 2003, 2004, 2005, 2006, 2007 by +# Copyright 2003, 2004, 2005, 2006, 2007, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -14,14 +14,14 @@ SubDir FT2_TOP src autofit ; { local _sources ; - # define FT2_AUTOFIT2 do enable to experimental latin hinter replacement + # define FT2_AUTOFIT2 to enable experimental latin hinter replacement if $(FT2_AUTOFIT2) { DEFINES += FT_OPTION_AUTOFIT2 ; } if $(FT2_MULTI) { - _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp ; + _sources = afangles afglobal afhints aflatin afcjk afindic afloader afmodule afdummy afwarp afpic ; if $(FT2_AUTOFIT2) { diff --git a/lib/3rdparty/freetype/src/autofit/afcjk.c b/lib/3rdparty/freetype/src/autofit/afcjk.c index c7ca266da8a..bab0c42bade 100644 --- a/lib/3rdparty/freetype/src/autofit/afcjk.c +++ b/lib/3rdparty/freetype/src/autofit/afcjk.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK script (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ /*************************************************************************/ /*************************************************************************/ - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_metrics_init( AF_LatinMetrics metrics, FT_Face face ) { @@ -58,9 +58,12 @@ if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) face->charmap = NULL; - - /* latin's version would suffice */ - af_latin_metrics_init_widths( metrics, face, 0x7530 ); + else + { + /* latin's version would suffice */ + af_latin_metrics_init_widths( metrics, face, 0x7530 ); + af_latin_metrics_check_digits( metrics, face ); + } FT_Set_Charmap( face, oldmap ); @@ -91,7 +94,7 @@ } - static void + FT_LOCAL_DEF( void ) af_cjk_metrics_scale( AF_LatinMetrics metrics, AF_Scaler scaler ) { @@ -427,7 +430,9 @@ /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); if ( error ) goto Exit; @@ -596,7 +601,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_init( AF_GlyphHints hints, AF_LatinMetrics metrics ) { @@ -1015,7 +1020,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; + FT_PtrDist n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Pos delta = 0; @@ -1251,10 +1256,15 @@ else if ( after >= edge_limit ) af_cjk_align_serif_edge( hints, before, edge ); else - edge->pos = before->pos + - FT_MulDiv( edge->fpos - before->fpos, - after->pos - before->pos, - after->fpos - before->fpos ); + { + if ( after->fpos == before->fpos ) + edge->pos = before->pos; + else + edge->pos = before->pos + + FT_MulDiv( edge->fpos - before->fpos, + after->pos - before->pos, + after->fpos - before->fpos ); + } } } } @@ -1350,7 +1360,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) af_cjk_hints_apply( AF_GlyphHints hints, FT_Outline* outline, AF_LatinMetrics metrics ) @@ -1434,35 +1444,33 @@ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { #if 0 - { 0x0100, 0xFFFF }, /* why this? */ + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ #endif - { 0x2E80, 0x2EFF }, /* CJK Radicals Supplement */ - { 0x2F00, 0x2FDF }, /* Kangxi Radicals */ - { 0x3000, 0x303F }, /* CJK Symbols and Punctuation */ - { 0x3040, 0x309F }, /* Hiragana */ - { 0x30A0, 0x30FF }, /* Katakana */ - { 0x3100, 0x312F }, /* Bopomofo */ - { 0x3130, 0x318F }, /* Hangul Compatibility Jamo */ - { 0x31A0, 0x31BF }, /* Bopomofo Extended */ - { 0x31C0, 0x31EF }, /* CJK Strokes */ - { 0x31F0, 0x31FF }, /* Katakana Phonetic Extensions */ - { 0x3200, 0x32FF }, /* Enclosed CJK Letters and Months */ - { 0x3300, 0x33FF }, /* CJK Compatibility */ - { 0x3400, 0x4DBF }, /* CJK Unified Ideographs Extension A */ - { 0x4DC0, 0x4DFF }, /* Yijing Hexagram Symbols */ - { 0x4E00, 0x9FFF }, /* CJK Unified Ideographs */ - { 0xF900, 0xFAFF }, /* CJK Compatibility Ideographs */ - { 0xFE30, 0xFE4F }, /* CJK Compatibility Forms */ - { 0xFF00, 0xFFEF }, /* Halfwidth and Fullwidth Forms */ - { 0x20000, 0x2A6DF }, /* CJK Unified Ideographs Extension B */ - { 0x2F800, 0x2FA1F }, /* CJK Compatibility Ideographs Supplement */ - { 0, 0 } + AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */ + AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_cjk_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, AF_SCRIPT_CJK, af_cjk_uniranges, @@ -1474,19 +1482,17 @@ (AF_Script_InitHintsFunc) af_cjk_hints_init, (AF_Script_ApplyHintsFunc) af_cjk_hints_apply - }; + ) #else /* !AF_CONFIG_OPTION_CJK */ static const AF_Script_UniRangeRec af_cjk_uniranges[] = { - { 0, 0 } + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_cjk_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class, AF_SCRIPT_CJK, af_cjk_uniranges, @@ -1498,7 +1504,7 @@ (AF_Script_InitHintsFunc) NULL, (AF_Script_ApplyHintsFunc) NULL - }; + ) #endif /* !AF_CONFIG_OPTION_CJK */ diff --git a/lib/3rdparty/freetype/src/autofit/afcjk.h b/lib/3rdparty/freetype/src/autofit/afcjk.h index 0de4a5ab728..0b20d4ae356 100644 --- a/lib/3rdparty/freetype/src/autofit/afcjk.h +++ b/lib/3rdparty/freetype/src/autofit/afcjk.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK script (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,10 +27,26 @@ FT_BEGIN_HEADER /* the CJK-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_cjk_script_class; + AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class) + FT_LOCAL( FT_Error ) + af_cjk_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_cjk_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_init( AF_GlyphHints hints, + AF_LatinMetrics metrics ); + + FT_LOCAL( FT_Error ) + af_cjk_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ); + /* */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/autofit/afdummy.c b/lib/3rdparty/freetype/src/autofit/afdummy.c index ed96e96410d..42b2fcb216d 100644 --- a/lib/3rdparty/freetype/src/autofit/afdummy.c +++ b/lib/3rdparty/freetype/src/autofit/afdummy.c @@ -42,9 +42,7 @@ } - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_dummy_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class, AF_SCRIPT_NONE, NULL, @@ -56,7 +54,7 @@ (AF_Script_InitHintsFunc) af_dummy_hints_init, (AF_Script_ApplyHintsFunc) af_dummy_hints_apply - }; + ) /* END */ diff --git a/lib/3rdparty/freetype/src/autofit/afdummy.h b/lib/3rdparty/freetype/src/autofit/afdummy.h index 2a5faf8f851..b69ef437fe9 100644 --- a/lib/3rdparty/freetype/src/autofit/afdummy.h +++ b/lib/3rdparty/freetype/src/autofit/afdummy.h @@ -29,8 +29,7 @@ FT_BEGIN_HEADER * be performed. This is the default for non-latin glyphs! */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_dummy_script_class; + AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class) /* */ diff --git a/lib/3rdparty/freetype/src/autofit/afglobal.c b/lib/3rdparty/freetype/src/autofit/afglobal.c index 1875f52befc..ac293619d3d 100644 --- a/lib/3rdparty/freetype/src/autofit/afglobal.c +++ b/lib/3rdparty/freetype/src/autofit/afglobal.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter routines to compute global hinting values (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,7 @@ #include "aflatin.h" #include "afcjk.h" #include "afindic.h" +#include "afpic.h" #include "aferrors.h" @@ -28,6 +29,11 @@ #include "aflatin2.h" #endif +#ifndef FT_CONFIG_OPTION_PIC + +/* when updating this table, don't forget to update + AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */ + /* populate this list when you add new scripts */ static AF_ScriptClass const af_script_classes[] = { @@ -37,14 +43,18 @@ #endif &af_latin_script_class, &af_cjk_script_class, - &af_indic_script_class, + &af_indic_script_class, NULL /* do not remove */ }; +#endif /* FT_CONFIG_OPTION_PIC */ + /* index of default script in `af_script_classes' */ #define AF_SCRIPT_LIST_DEFAULT 2 - /* indicates an uncovered glyph */ -#define AF_SCRIPT_LIST_NONE 255 + /* a bit mask indicating an uncovered glyph */ +#define AF_SCRIPT_LIST_NONE 0x7F + /* if this flag is set, we have an ASCII digit */ +#define AF_DIGIT 0x80 /* @@ -55,7 +65,7 @@ typedef struct AF_FaceGlobalsRec_ { FT_Face face; - FT_UInt glyph_count; /* same as face->num_glyphs */ + FT_Long glyph_count; /* same as face->num_glyphs */ FT_Byte* glyph_scripts; AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; @@ -72,7 +82,7 @@ FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gscripts = globals->glyph_scripts; - FT_UInt ss; + FT_UInt ss, i; /* the value 255 means `uncovered glyph' */ @@ -84,17 +94,17 @@ if ( error ) { /* - * Ignore this error; we simply use Latin as the standard - * script. XXX: Shouldn't we rather disable hinting? + * Ignore this error; we simply use the default script. + * XXX: Shouldn't we rather disable hinting? */ error = AF_Err_Ok; goto Exit; } /* scan each script in a Unicode charmap */ - for ( ss = 0; af_script_classes[ss]; ss++ ) + for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) { - AF_ScriptClass clazz = af_script_classes[ss]; + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; AF_Script_UniRange range; @@ -114,7 +124,7 @@ gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && - gindex < globals->glyph_count && + gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; @@ -127,7 +137,7 @@ if ( gindex == 0 || charcode > range->last ) break; - if ( gindex < globals->glyph_count && + if ( gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; @@ -136,13 +146,23 @@ } } + /* mark ASCII digits */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt gindex = FT_Get_Char_Index( face, i ); + + + if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) + gscripts[gindex] |= AF_DIGIT; + } + Exit: /* * By default, all uncovered glyphs are set to the latin script. * XXX: Shouldn't we disable hinting or do something similar? */ { - FT_UInt nn; + FT_Long nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) @@ -201,7 +221,7 @@ { if ( globals->metrics[nn] ) { - AF_ScriptClass clazz = af_script_classes[nn]; + AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[nn]; FT_ASSERT( globals->metrics[nn]->clazz == clazz ); @@ -232,12 +252,12 @@ FT_UInt gidx; AF_ScriptClass clazz; FT_UInt script = options & 15; - const FT_UInt script_max = sizeof ( af_script_classes ) / - sizeof ( af_script_classes[0] ); + const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / + sizeof ( AF_SCRIPT_CLASSES_GET[0] ); FT_Error error = AF_Err_Ok; - if ( gindex >= globals->glyph_count ) + if ( gindex >= (FT_ULong)globals->glyph_count ) { error = AF_Err_Invalid_Argument; goto Exit; @@ -245,9 +265,9 @@ gidx = script; if ( gidx == 0 || gidx + 1 >= script_max ) - gidx = globals->glyph_scripts[gindex]; + gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE; - clazz = af_script_classes[gidx]; + clazz = AF_SCRIPT_CLASSES_GET[gidx]; if ( script == 0 ) script = clazz->script; @@ -286,4 +306,15 @@ } + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ) + { + if ( gindex < (FT_ULong)globals->glyph_count ) + return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); + + return (FT_Bool)0; + } + + /* END */ diff --git a/lib/3rdparty/freetype/src/autofit/afglobal.h b/lib/3rdparty/freetype/src/autofit/afglobal.h index cf52c087560..2a68e19607a 100644 --- a/lib/3rdparty/freetype/src/autofit/afglobal.h +++ b/lib/3rdparty/freetype/src/autofit/afglobal.h @@ -5,7 +5,7 @@ /* Auto-fitter routines to compute global hinting values */ /* (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2007 by */ +/* Copyright 2003, 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,7 +56,11 @@ FT_BEGIN_HEADER FT_LOCAL( void ) af_face_globals_free( AF_FaceGlobals globals ); - /* */ + FT_LOCAL_DEF( FT_Bool ) + af_face_globals_is_digit( AF_FaceGlobals globals, + FT_UInt gindex ); + + /* */ FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/autofit/afhints.c b/lib/3rdparty/freetype/src/autofit/afhints.c index 482870686d5..fe38fba9954 100644 --- a/lib/3rdparty/freetype/src/autofit/afhints.c +++ b/lib/3rdparty/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,7 +34,7 @@ { FT_Int old_max = axis->max_segments; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof ( *segment ); + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) ); if ( old_max >= big_max ) @@ -77,7 +77,7 @@ { FT_Int old_max = axis->max_edges; FT_Int new_max = old_max; - FT_Int big_max = FT_INT_MAX / sizeof ( *edge ); + FT_Int big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) ); if ( old_max >= big_max ) @@ -127,7 +127,7 @@ #ifdef AF_DEBUG -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H static const char* af_dir_str( AF_Direction dir ) @@ -203,14 +203,14 @@ if ( flags & AF_EDGE_ROUND ) { - memcpy( temp + pos, "round", 5 ); + ft_memcpy( temp + pos, "round", 5 ); pos += 5; } if ( flags & AF_EDGE_SERIF ) { if ( pos > 0 ) temp[pos++] = ' '; - memcpy( temp + pos, "serif", 5 ); + ft_memcpy( temp + pos, "serif", 5 ); pos += 5; } if ( pos == 0 ) @@ -645,6 +645,7 @@ FT_Int contour_index = 0; + FT_UNUSED( first ); for ( point = points; point < point_limit; point++, vec++, tag++ ) { point->fx = (FT_Short)vec->x; @@ -940,8 +941,8 @@ } { - FT_UInt min, max, mid; - FT_Pos fpos; + FT_PtrDist min, max, mid; + FT_Pos fpos; /* find enclosing edges */ @@ -952,7 +953,7 @@ /* for small edge counts, a linear search is better */ if ( max <= 8 ) { - FT_UInt nn; + FT_PtrDist nn; for ( nn = 0; nn < max; nn++ ) if ( edges[nn].fpos >= u ) diff --git a/lib/3rdparty/freetype/src/autofit/afhints.h b/lib/3rdparty/freetype/src/autofit/afhints.h index 49e88d1b621..675826835ae 100644 --- a/lib/3rdparty/freetype/src/autofit/afhints.h +++ b/lib/3rdparty/freetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,7 +30,7 @@ FT_BEGIN_HEADER * script analysis routines (until now). */ - typedef enum + typedef enum AF_Dimension_ { AF_DIMENSION_HORZ = 0, /* x coordinates, */ /* i.e., vertical segments & edges */ @@ -44,7 +44,7 @@ FT_BEGIN_HEADER /* hint directions -- the values are computed so that two vectors are */ /* in opposite directions iff `dir1 + dir2 == 0' */ - typedef enum + typedef enum AF_Direction_ { AF_DIR_NONE = 4, AF_DIR_RIGHT = 1, @@ -56,7 +56,7 @@ FT_BEGIN_HEADER /* point hint flags */ - typedef enum + typedef enum AF_Flags_ { AF_FLAG_NONE = 0, @@ -87,7 +87,7 @@ FT_BEGIN_HEADER /* edge hint flags */ - typedef enum + typedef enum AF_Edge_Flags_ { AF_EDGE_NORMAL = 0, AF_EDGE_ROUND = 1 << 0, @@ -214,7 +214,7 @@ FT_BEGIN_HEADER FT_Pos xmin_delta; /* used for warping */ FT_Pos xmax_delta; - + } AF_GlyphHintsRec; diff --git a/lib/3rdparty/freetype/src/autofit/afindic.c b/lib/3rdparty/freetype/src/autofit/afindic.c index c6e7522e15b..1d9e9eafbad 100644 --- a/lib/3rdparty/freetype/src/autofit/afindic.c +++ b/lib/3rdparty/freetype/src/autofit/afindic.c @@ -43,7 +43,7 @@ static void af_indic_metrics_scale( AF_LatinMetrics metrics, - AF_Scaler scaler ) + AF_Scaler scaler ) { /* use CJK routines */ af_cjk_metrics_scale( metrics, scaler ); @@ -52,7 +52,7 @@ static FT_Error af_indic_hints_init( AF_GlyphHints hints, - AF_LatinMetrics metrics ) + AF_LatinMetrics metrics ) { /* use CJK routines */ return af_cjk_hints_init( hints, metrics ); @@ -61,8 +61,8 @@ static FT_Error af_indic_hints_apply( AF_GlyphHints hints, - FT_Outline* outline, - AF_LatinMetrics metrics) + FT_Outline* outline, + AF_LatinMetrics metrics) { /* use CJK routines */ return af_cjk_hints_apply( hints, outline, metrics ); @@ -81,16 +81,14 @@ static const AF_Script_UniRangeRec af_indic_uniranges[] = { #if 0 - { 0x0100, 0xFFFF }, /* why this? */ + AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ), /* why this? */ #endif - { 0x0900, 0x0DFF}, /* Indic Range */ - { 0, 0 } + AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL), /* Indic Range */ + AF_UNIRANGE_REC( 0UL, 0UL) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_indic_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, AF_SCRIPT_INDIC, af_indic_uniranges, @@ -102,7 +100,7 @@ (AF_Script_InitHintsFunc) af_indic_hints_init, (AF_Script_ApplyHintsFunc) af_indic_hints_apply - }; + ) #else /* !AF_CONFIG_OPTION_INDIC */ @@ -112,9 +110,7 @@ }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_indic_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_indic_script_class, AF_SCRIPT_INDIC, af_indic_uniranges, @@ -126,7 +122,7 @@ (AF_Script_InitHintsFunc) NULL, (AF_Script_ApplyHintsFunc) NULL - }; + ) #endif /* !AF_CONFIG_OPTION_INDIC */ diff --git a/lib/3rdparty/freetype/src/autofit/afindic.h b/lib/3rdparty/freetype/src/autofit/afindic.h index b242b261443..662a982200e 100644 --- a/lib/3rdparty/freetype/src/autofit/afindic.h +++ b/lib/3rdparty/freetype/src/autofit/afindic.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the Indic-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_indic_script_class; + AF_DECLARE_SCRIPT_CLASS(af_indic_script_class) /* */ diff --git a/lib/3rdparty/freetype/src/autofit/aflatin.c b/lib/3rdparty/freetype/src/autofit/aflatin.c index 52e952d9885..e6882d5e7b5 100644 --- a/lib/3rdparty/freetype/src/autofit/aflatin.c +++ b/lib/3rdparty/freetype/src/autofit/aflatin.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,6 +16,9 @@ /***************************************************************************/ +#include <ft2build.h> +#include FT_ADVANCES_H + #include "aflatin.h" #include "aferrors.h" @@ -146,7 +149,8 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin_blue_chars[AF_LATIN_MAX_BLUES] = + static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES] + [AF_LATIN_MAX_TEST_CHARACTERS + 1] = { "THEZOCQS", "HEZLOCUS", @@ -195,7 +199,8 @@ for ( ; p < limit && *p; p++ ) { FT_UInt glyph_index; - FT_Int best_point, best_y, best_first, best_last; + FT_Pos best_y; /* same as points.y */ + FT_Int best_point, best_first, best_last; FT_Vector* points; FT_Bool round = 0; @@ -328,7 +333,7 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - AF_LOG(( "empty!\n" )); + AF_LOG(( "empty\n" )); continue; } @@ -379,7 +384,7 @@ blue->flags |= AF_LATIN_BLUE_TOP; /* - * The following flags is used later to adjust the y and x scales + * The following flag is used later to adjust the y and x scales * in order to optimize the pixel grid alignment of the top of small * letters. */ @@ -393,6 +398,52 @@ } + FT_LOCAL_DEF( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + FT_LOCAL_DEF( FT_Error ) af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ) @@ -426,6 +477,7 @@ /* For now, compute the standard width and height from the `o'. */ af_latin_metrics_init_widths( metrics, face, 'o' ); af_latin_metrics_init_blues( metrics, face ); + af_latin_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); @@ -1004,12 +1056,14 @@ if ( !found ) { - AF_Edge edge; + AF_Edge edge; /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge ); + error = af_axis_hints_new_edge( axis, seg->pos, + (AF_Direction)seg->dir, + memory, &edge ); if ( error ) goto Exit; @@ -1565,7 +1619,7 @@ /* not hinted, appear a lot bolder or thinner than the */ /* vertical stems. */ - FT_Int delta; + FT_Pos delta; dist = ( dist + 22 ) & ~63; @@ -1649,7 +1703,7 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; + FT_PtrDist n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Int has_serifs = 0; @@ -2006,7 +2060,10 @@ if ( before >= edges && before < edge && after < edge_limit && after > edge ) { - edge->pos = before->pos + + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + FT_MulDiv( edge->opos - before->opos, after->pos - before->pos, after->opos - before->opos ); @@ -2122,33 +2179,37 @@ static const AF_Script_UniRangeRec af_latin_uniranges[] = { - { 0x0020, 0x007F }, /* Basic Latin (no control characters) */ - { 0x00A0, 0x00FF }, /* Latin-1 Supplement (no control characters) */ - { 0x0100, 0x017F }, /* Latin Extended-A */ - { 0x0180, 0x024F }, /* Latin Extended-B */ - { 0x0250, 0x02AF }, /* IPA Extensions */ - { 0x02B0, 0x02FF }, /* Spacing Modifier Letters */ - { 0x0300, 0x036F }, /* Combining Diacritical Marks */ - { 0x0370, 0x03FF }, /* Greek and Coptic */ - { 0x0400, 0x04FF }, /* Cyrillic */ - { 0x0500, 0x052F }, /* Cyrillic Supplement */ - { 0x1D00, 0x1D7F }, /* Phonetic Extensions */ - { 0x1D80, 0x1DBF }, /* Phonetic Extensions Supplement */ - { 0x1DC0, 0x1DFF }, /* Combining Diacritical Marks Supplement */ - { 0x1E00, 0x1EFF }, /* Latin Extended Additional */ - { 0x1F00, 0x1FFF }, /* Greek Extended */ - { 0x2000, 0x206F }, /* General Punctuation */ - { 0x2070, 0x209F }, /* Superscripts and Subscripts */ - { 0x20A0, 0x20CF }, /* Currency Symbols */ - { 0x2150, 0x218F }, /* Number Forms */ - { 0x2460, 0x24FF }, /* Enclosed Alphanumerics */ - { 0 , 0 } + AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0UL, 0x00FFUL ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B0UL, 0x02FFUL ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x1D00UL, 0x1D7FUL ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D80UL, 0x1DBFUL ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ + AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x2070UL, 0x209FUL ), /* Superscripts and Subscripts */ + AF_UNIRANGE_REC( 0x20A0UL, 0x20CFUL ), /* Currency Symbols */ + AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */ + AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_latin_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_latin_script_class, AF_SCRIPT_LATIN, af_latin_uniranges, @@ -2160,7 +2221,7 @@ (AF_Script_InitHintsFunc) af_latin_hints_init, (AF_Script_ApplyHintsFunc) af_latin_hints_apply - }; + ) /* END */ diff --git a/lib/3rdparty/freetype/src/autofit/aflatin.h b/lib/3rdparty/freetype/src/autofit/aflatin.h index 3251d3783f3..660b10c83f7 100644 --- a/lib/3rdparty/freetype/src/autofit/aflatin.h +++ b/lib/3rdparty/freetype/src/autofit/aflatin.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (specification). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the latin-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_latin_script_class; + AF_DECLARE_SCRIPT_CLASS(af_latin_script_class) /* constants are given with units_per_em == 2048 in mind */ @@ -138,6 +137,10 @@ FT_BEGIN_HEADER FT_Face face, FT_ULong charcode ); + FT_LOCAL( void ) + af_latin_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ); + /*************************************************************************/ /*************************************************************************/ diff --git a/lib/3rdparty/freetype/src/autofit/aflatin2.c b/lib/3rdparty/freetype/src/autofit/aflatin2.c index 0b4177414c1..5cbeb296b58 100644 --- a/lib/3rdparty/freetype/src/autofit/aflatin2.c +++ b/lib/3rdparty/freetype/src/autofit/aflatin2.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin script (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,6 +16,8 @@ /***************************************************************************/ +#include FT_ADVANCES_H + #include "aflatin.h" #include "aflatin2.h" #include "aferrors.h" @@ -154,7 +156,7 @@ #define AF_LATIN_MAX_TEST_CHARACTERS 12 - static const char* const af_latin2_blue_chars[AF_LATIN_MAX_BLUES] = + static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] = { "THEZOCQS", "HEZLOCUS", @@ -336,7 +338,7 @@ * we couldn't find a single glyph to compute this blue zone, * we will simply ignore it then */ - AF_LOG(( "empty!\n" )); + AF_LOG(( "empty\n" )); continue; } @@ -401,6 +403,52 @@ } + FT_LOCAL_DEF( void ) + af_latin2_metrics_check_digits( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_UInt i; + FT_Bool started = 0, same_width = 1; + FT_Fixed advance, old_advance = 0; + + + /* check whether all ASCII digits have the same advance width; */ + /* digit `0' is 0x30 in all supported charmaps */ + for ( i = 0x30; i <= 0x39; i++ ) + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( face, i ); + if ( glyph_index == 0 ) + continue; + + if ( FT_Get_Advance( face, glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + &advance ) ) + continue; + + if ( started ) + { + if ( advance != old_advance ) + { + same_width = 0; + break; + } + } + else + { + old_advance = advance; + started = 1; + } + } + + metrics->root.digits_have_same_width = same_width; + } + + FT_LOCAL_DEF( FT_Error ) af_latin2_metrics_init( AF_LatinMetrics metrics, FT_Face face ) @@ -434,6 +482,7 @@ /* For now, compute the standard width and height from the `o'. */ af_latin2_metrics_init_widths( metrics, face, 'o' ); af_latin2_metrics_init_blues( metrics, face ); + af_latin2_metrics_check_digits( metrics, face ); } FT_Set_Charmap( face, oldmap ); @@ -944,6 +993,9 @@ } } } +#if 0 + } +#endif /* now, compute the `serif' segments */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) @@ -1736,7 +1788,6 @@ AF_AxisHints axis = &hints->axis[dim]; AF_Edge edges = axis->edges; AF_Edge edge_limit = edges + axis->num_edges; - FT_Int n_edges; AF_Edge edge; AF_Edge anchor = 0; FT_Int has_serifs = 0; @@ -2047,54 +2098,60 @@ /* We don't handle horizontal edges since we can't easily assure that */ /* the third (lowest) stem aligns with the base line; it might end up */ /* one pixel higher or lower. */ + #if 0 - n_edges = edge_limit - edges; - if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) { - AF_Edge edge1, edge2, edge3; - FT_Pos dist1, dist2, span, delta; + FT_Int n_edges = edge_limit - edges; - if ( n_edges == 6 ) + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) { - edge1 = edges; - edge2 = edges + 2; - edge3 = edges + 4; - } - else - { - edge1 = edges + 1; - edge2 = edges + 5; - edge3 = edges + 9; - } + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; - dist1 = edge2->opos - edge1->opos; - dist2 = edge3->opos - edge2->opos; - span = dist1 - dist2; - if ( span < 0 ) - span = -span; - - if ( span < 8 ) - { - delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); - edge3->pos -= delta; - if ( edge3->link ) - edge3->link->pos -= delta; - - /* move the serifs along with the stem */ - if ( n_edges == 12 ) + if ( n_edges == 6 ) { - ( edges + 8 )->pos -= delta; - ( edges + 11 )->pos -= delta; + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; } - edge3->flags |= AF_EDGE_DONE; - if ( edge3->link ) - edge3->link->flags |= AF_EDGE_DONE; + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } } } #endif + if ( has_serifs || !anchor ) { /* @@ -2150,7 +2207,10 @@ if ( before >= edges && before < edge && after < edge_limit && after > edge ) { - edge->pos = before->pos + + if ( after->opos == before->opos ) + edge->pos = before->pos; + else + edge->pos = before->pos + FT_MulDiv( edge->opos - before->opos, after->pos - before->pos, after->opos - before->opos ); @@ -2260,15 +2320,13 @@ static const AF_Script_UniRangeRec af_latin2_uniranges[] = { - { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here! */ - { 160, 255 }, - { 0, 0 } + AF_UNIRANGE_REC( 32UL, 127UL ), /* XXX: TODO: Add new Unicode ranges here! */ + AF_UNIRANGE_REC( 160UL, 255UL ), + AF_UNIRANGE_REC( 0UL, 0UL ) }; - FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec - af_latin2_script_class = - { + AF_DEFINE_SCRIPT_CLASS(af_latin2_script_class, AF_SCRIPT_LATIN2, af_latin2_uniranges, @@ -2280,7 +2338,7 @@ (AF_Script_InitHintsFunc) af_latin2_hints_init, (AF_Script_ApplyHintsFunc) af_latin2_hints_apply - }; + ) /* END */ diff --git a/lib/3rdparty/freetype/src/autofit/aflatin2.h b/lib/3rdparty/freetype/src/autofit/aflatin2.h index 34eda058229..925c6214db3 100644 --- a/lib/3rdparty/freetype/src/autofit/aflatin2.h +++ b/lib/3rdparty/freetype/src/autofit/aflatin2.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER /* the latin-specific script class */ - FT_CALLBACK_TABLE const AF_ScriptClassRec - af_latin2_script_class; + AF_DECLARE_SCRIPT_CLASS(af_latin2_script_class) /* */ diff --git a/lib/3rdparty/freetype/src/autofit/afloader.c b/lib/3rdparty/freetype/src/autofit/afloader.c index 4e4373a4924..6dd9f2a314a 100644 --- a/lib/3rdparty/freetype/src/autofit/afloader.c +++ b/lib/3rdparty/freetype/src/autofit/afloader.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,7 +19,6 @@ #include "afloader.h" #include "afhints.h" #include "afglobal.h" -#include "aflatin.h" #include "aferrors.h" @@ -165,9 +164,10 @@ /* now load the slot image into the auto-outline and run the */ /* automatic hinting process */ - metrics->clazz->script_hints_apply( hints, - &gloader->current.outline, - metrics ); + if ( metrics->clazz->script_hints_apply ) + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); /* we now need to hint the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ @@ -183,9 +183,9 @@ if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) { - old_rsb = loader->pp2.x - edge2->opos; - old_lsb = edge1->opos; - new_lsb = edge1->pos; + old_rsb = loader->pp2.x - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; /* remember unhinted values to later account */ /* for rounding errors */ @@ -216,8 +216,9 @@ } else { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + loader->pp1.x = FT_PIX_ROUND( pp1x ); loader->pp2.x = FT_PIX_ROUND( pp2x ); @@ -228,8 +229,9 @@ } else { - FT_Pos pp1x = loader->pp1.x; - FT_Pos pp2x = loader->pp2.x; + FT_Pos pp1x = loader->pp1.x; + FT_Pos pp2x = loader->pp2.x; + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); @@ -412,7 +414,8 @@ slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y ); /* for mono-width fonts (like Andale, Courier, etc.) we need */ - /* to keep the original rounded advance width */ + /* to keep the original rounded advance width; ditto for */ + /* digits if all have the same advance width */ #if 0 if ( !FT_IS_FIXED_WIDTH( slot->face ) ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; @@ -420,13 +423,9 @@ slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); #else - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - { - /* non-spacing glyphs must stay as-is */ - if ( slot->metrics.horiAdvance ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - } - else + if ( FT_IS_FIXED_WIDTH( slot->face ) || + ( af_face_globals_is_digit( loader->globals, glyph_index ) && + metrics->digits_have_same_width ) ) { slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, metrics->scaler.x_scale ); @@ -436,6 +435,12 @@ slot->lsb_delta = 0; slot->rsb_delta = 0; } + else + { + /* non-spacing glyphs must stay as-is */ + if ( slot->metrics.horiAdvance ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + } #endif slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, @@ -515,9 +520,13 @@ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; load_flags &= ~FT_LOAD_RENDER; - error = metrics->clazz->script_hints_init( &loader->hints, metrics ); - if ( error ) - goto Exit; + if ( metrics->clazz->script_hints_init ) + { + error = metrics->clazz->script_hints_init( &loader->hints, + metrics ); + if ( error ) + goto Exit; + } error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); } diff --git a/lib/3rdparty/freetype/src/autofit/afmodule.c b/lib/3rdparty/freetype/src/autofit/afmodule.c index cd5e1cc218b..ec2d707c9f9 100644 --- a/lib/3rdparty/freetype/src/autofit/afmodule.c +++ b/lib/3rdparty/freetype/src/autofit/afmodule.c @@ -18,6 +18,7 @@ #include "afmodule.h" #include "afloader.h" +#include "afpic.h" #ifdef AF_DEBUG int _af_debug; @@ -66,19 +67,15 @@ } - FT_CALLBACK_TABLE_DEF - const FT_AutoHinter_ServiceRec af_autofitter_service = - { + FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service, NULL, NULL, NULL, (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph - }; + ) + FT_DEFINE_MODULE(autofit_module_class, - FT_CALLBACK_TABLE_DEF - const FT_Module_Class autofit_module_class = - { FT_MODULE_HINTER, sizeof ( FT_AutofitterRec ), @@ -86,12 +83,12 @@ 0x10000L, /* version 1.0 of the autofitter */ 0x20000L, /* requires FreeType 2.0 or above */ - (const void*)&af_autofitter_service, + (const void*)&AF_AF_AUTOFITTER_SERVICE_GET, (FT_Module_Constructor)af_autofitter_init, (FT_Module_Destructor) af_autofitter_done, (FT_Module_Requester) NULL - }; + ) /* END */ diff --git a/lib/3rdparty/freetype/src/autofit/afmodule.h b/lib/3rdparty/freetype/src/autofit/afmodule.h index 36268a0890a..d9792399b63 100644 --- a/lib/3rdparty/freetype/src/autofit/afmodule.h +++ b/lib/3rdparty/freetype/src/autofit/afmodule.h @@ -20,13 +20,13 @@ #define __AFMODULE_H__ #include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H #include FT_MODULE_H FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Module_Class autofit_module_class; +FT_DECLARE_MODULE(autofit_module_class) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/autofit/afpic.c b/lib/3rdparty/freetype/src/autofit/afpic.c new file mode 100644 index 00000000000..76822c301a8 --- /dev/null +++ b/lib/3rdparty/freetype/src/autofit/afpic.c @@ -0,0 +1,92 @@ +/***************************************************************************/ +/* */ +/* afpic.c */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "afpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from afmodule.c */ + void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*); + + /* forward declaration of PIC init functions from script classes */ +#include "aflatin.h" +#include "aflatin2.h" +#include "afcjk.h" +#include "afdummy.h" +#include "afindic.h" + + void + autofit_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->autofit ) + { + FT_FREE( pic_container->autofit ); + pic_container->autofit = NULL; + } + } + + FT_Error + autofit_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_UInt ss; + FT_Error error = FT_Err_Ok; + AFModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->autofit = container; + + /* initialize pointer table - this is how the module usually expects this data */ + for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) + { + container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; + } + container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL; + + /* add call to initialization function when you add new scripts */ + ss = 0; + FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]); +#ifdef FT_OPTION_AUTOFIT2 + FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]); +#endif + FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]); + FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]); + + FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service); + +/*Exit:*/ + if(error) + autofit_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/autofit/afpic.h b/lib/3rdparty/freetype/src/autofit/afpic.h new file mode 100644 index 00000000000..80e62d39a99 --- /dev/null +++ b/lib/3rdparty/freetype/src/autofit/afpic.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* afpic.h */ +/* */ +/* The FreeType position independent code services for autofit module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __AFPIC_H__ +#define __AFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_SCRIPT_CLASSES_GET af_script_classes +#define AF_AF_AUTOFITTER_SERVICE_GET af_autofitter_service + +#else /* FT_CONFIG_OPTION_PIC */ + +#include "aftypes.h" + +/* increase these when you add new scripts, and update autofit_module_class_pic_init */ +#ifdef FT_OPTION_AUTOFIT2 + #define AF_SCRIPT_CLASSES_COUNT 6 +#else + #define AF_SCRIPT_CLASSES_COUNT 5 +#endif +#define AF_SCRIPT_CLASSES_REC_COUNT (AF_SCRIPT_CLASSES_COUNT-1) + + typedef struct AFModulePIC_ + { + AF_ScriptClass af_script_classes[AF_SCRIPT_CLASSES_COUNT]; + AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT]; + FT_AutoHinter_ServiceRec af_autofitter_service; + } AFModulePIC; + +#define GET_PIC(lib) ((AFModulePIC*)((lib)->pic_container.autofit)) +#define AF_SCRIPT_CLASSES_GET (GET_PIC(FT_FACE_LIBRARY(globals->face))->af_script_classes) +#define AF_AF_AUTOFITTER_SERVICE_GET (GET_PIC(library)->af_autofitter_service) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __AFPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/autofit/aftypes.h b/lib/3rdparty/freetype/src/autofit/aftypes.h index 9c27df2d9f0..5574f0c302b 100644 --- a/lib/3rdparty/freetype/src/autofit/aftypes.h +++ b/lib/3rdparty/freetype/src/autofit/aftypes.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter types (specification only). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,7 +58,8 @@ FT_BEGIN_HEADER #ifdef AF_DEBUG -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H + #define AF_LOG( x ) do { if ( _af_debug ) printf x; } while ( 0 ) extern int _af_debug; @@ -69,7 +70,7 @@ extern void* _af_debug_hints; #else /* !AF_DEBUG */ -#define AF_LOG( x ) do ; while ( 0 ) /* nothing */ +#define AF_LOG( x ) do { } while ( 0 ) /* nothing */ #endif /* !AF_DEBUG */ @@ -202,7 +203,7 @@ extern void* _af_debug_hints; * auto-hinted glyph image. */ - typedef enum + typedef enum AF_ScalerFlags_ { AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ @@ -260,12 +261,12 @@ extern void* _af_debug_hints; * used by more than one script. */ - typedef enum + typedef enum AF_Script_ { AF_SCRIPT_NONE = 0, AF_SCRIPT_LATIN = 1, AF_SCRIPT_CJK = 2, - AF_SCRIPT_INDIC = 3, + AF_SCRIPT_INDIC = 3, #ifdef FT_OPTION_AUTOFIT2 AF_SCRIPT_LATIN2, #endif @@ -284,6 +285,7 @@ extern void* _af_debug_hints; { AF_ScriptClass clazz; AF_ScalerRec scaler; + FT_Bool digits_have_same_width; } AF_ScriptMetricsRec, *AF_ScriptMetrics; @@ -320,6 +322,8 @@ extern void* _af_debug_hints; } AF_Script_UniRangeRec; +#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) } + typedef const AF_Script_UniRangeRec *AF_Script_UniRange; @@ -328,7 +332,7 @@ extern void* _af_debug_hints; AF_Script script; AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ - FT_UInt script_metrics_size; + FT_Offset script_metrics_size; AF_Script_InitMetricsFunc script_metrics_init; AF_Script_ScaleMetricsFunc script_metrics_scale; AF_Script_DoneMetricsFunc script_metrics_done; @@ -338,6 +342,56 @@ extern void* _af_debug_hints; } AF_ScriptClassRec; +/* Declare and define vtables for classes */ +#ifndef FT_CONFIG_OPTION_PIC + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_CALLBACK_TABLE const AF_ScriptClassRec \ + script_class; + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec \ + script_class = \ + { \ + script_, \ + ranges, \ + \ + m_size, \ + \ + m_init, \ + m_scale, \ + m_done, \ + \ + h_init, \ + h_apply \ + }; + +#else + +#define AF_DECLARE_SCRIPT_CLASS(script_class) \ + FT_LOCAL(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac); + +#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size, \ + m_init, m_scale, m_done, h_init, h_apply) \ + FT_LOCAL_DEF(void) \ + FT_Init_Class_##script_class(AF_ScriptClassRec* ac) \ + { \ + ac->script = script_; \ + ac->script_uni_ranges = ranges; \ + \ + ac->script_metrics_size = m_size; \ + \ + ac->script_metrics_init = m_init; \ + ac->script_metrics_scale = m_scale; \ + ac->script_metrics_done = m_done; \ + \ + ac->script_hints_init = h_init; \ + ac->script_hints_apply = h_apply; \ + } +#endif + /* */ diff --git a/lib/3rdparty/freetype/src/autofit/afwarp.c b/lib/3rdparty/freetype/src/autofit/afwarp.c index 6c31cffc4e1..f5bb9b18ad9 100644 --- a/lib/3rdparty/freetype/src/autofit/afwarp.c +++ b/lib/3rdparty/freetype/src/autofit/afwarp.c @@ -317,7 +317,7 @@ { FT_Fixed best_scale = warper->best_scale; FT_Pos best_delta = warper->best_delta; - + hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale ) + best_delta; diff --git a/lib/3rdparty/freetype/src/autofit/autofit.c b/lib/3rdparty/freetype/src/autofit/autofit.c index 2fe66a990ec..83b613e79b3 100644 --- a/lib/3rdparty/freetype/src/autofit/autofit.c +++ b/lib/3rdparty/freetype/src/autofit/autofit.c @@ -18,6 +18,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "afpic.c" #include "afangles.c" #include "afglobal.c" #include "afhints.c" diff --git a/lib/3rdparty/freetype/src/autofit/module.mk b/lib/3rdparty/freetype/src/autofit/module.mk index 4a386ce66cc..6ec60912ab7 100644 --- a/lib/3rdparty/freetype/src/autofit/module.mk +++ b/lib/3rdparty/freetype/src/autofit/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += AUTOFIT_MODULE define AUTOFIT_MODULE -$(OPEN_DRIVER)autofit_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, autofit_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)autofit $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/base/Jamfile b/lib/3rdparty/freetype/src/base/Jamfile index aeffe388e58..832e8b84249 100644 --- a/lib/3rdparty/freetype/src/base/Jamfile +++ b/lib/3rdparty/freetype/src/base/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/base Jamfile # -# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -17,8 +17,11 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; if $(FT2_MULTI) { - _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln - ftobjs ftnames ftrfork ; + _sources = ftadvanc ftcalc ftdbgmem ftgloadr + ftobjs ftoutln ftrfork ftsnames + ftstream fttrigon ftutil + basepic ftpic + ; } else { @@ -31,11 +34,11 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; # Add the optional/replaceable files. # { - local _sources = system init glyph mm bdf - bbox debug xf86 type1 pfr - stroke winfnt otval bitmap synth - gxval lcdfil gasp patent - ; + local _sources = bbox bdf bitmap debug gasp + glyph gxval init lcdfil mm + otval pfr stroke synth system + type1 winfnt xf86 patent + ; Library $(FT2_LIB) : ft$(_sources).c ; } @@ -46,5 +49,12 @@ if $(MAC) { Library $(FT2_LIB) : ftmac.c ; } +else if $(OS) = MACOSX +{ + if $(FT2_MULTI) + { + Library $(FT2_LIB) : ftmac.c ; + } +} # end of src/base Jamfile diff --git a/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c b/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c deleted file mode 100644 index b5d448c9509..00000000000 --- a/lib/3rdparty/freetype/src/base/_ftmulfix_ros.c +++ /dev/null @@ -1,92 +0,0 @@ - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { - /* use inline assembly to speed up things a bit */ - -#if defined( __GNUC__ ) && defined( i386 ) - - FT_Long result; - - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - "mov %%eax, %0\n" - : "=r"(result), "=d"(b) - : "a"(a), "d"(b) - : "%ecx" - ); - return result; - -#elif 1 - - FT_Long sa, sb; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFU; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); - } - - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); - - return (FT_Long)ua; - -#else /* 0 */ - - FT_Long s; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000UL ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFUL; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); - } - - return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); - -#endif /* 0 */ - - } diff --git a/lib/3rdparty/freetype/src/base/basepic.c b/lib/3rdparty/freetype/src/base/basepic.c new file mode 100644 index 00000000000..c0bccb6959b --- /dev/null +++ b/lib/3rdparty/freetype/src/base/basepic.c @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* basepic.c */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftglyph.c */ + void FT_Init_Class_ft_outline_glyph_class(FT_Glyph_Class*); + void FT_Init_Class_ft_bitmap_glyph_class(FT_Glyph_Class*); + + /* forward declaration of PIC init functions from ftinit.c */ + FT_Error ft_create_default_module_classes(FT_Library); + void ft_destroy_default_module_classes(FT_Library); + + void + ft_base_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->base ) + { + /* Destroy default module classes (in case FT_Add_Default_Modules was used) */ + ft_destroy_default_module_classes( library ); + + FT_FREE( pic_container->base ); + pic_container->base = NULL; + } + } + + + FT_Error + ft_base_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + BasePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->base = container; + + /* initialize default modules list and pointers */ + error = ft_create_default_module_classes( library ); + if ( error ) + goto Exit; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_outline_glyph_class(&container->ft_outline_glyph_class); + FT_Init_Class_ft_bitmap_glyph_class(&container->ft_bitmap_glyph_class); + +Exit: + if(error) + ft_base_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/basepic.h b/lib/3rdparty/freetype/src/base/basepic.h new file mode 100644 index 00000000000..bb17745769e --- /dev/null +++ b/lib/3rdparty/freetype/src/base/basepic.h @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* basepic.h */ +/* */ +/* The FreeType position independent code services for base. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __BASEPIC_H__ +#define __BASEPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class +#define FT_BITMAP_GLYPH_CLASS_GET &ft_bitmap_glyph_class +#define FT_DEFAULT_MODULES_GET ft_default_modules + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_GLYPH_H + + typedef struct BasePIC_ + { + FT_Module_Class** default_module_classes; + FT_Glyph_Class ft_outline_glyph_class; + FT_Glyph_Class ft_bitmap_glyph_class; + } BasePIC; + +#define GET_PIC(lib) ((BasePIC*)((lib)->pic_container.base)) +#define FT_OUTLINE_GLYPH_CLASS_GET (&GET_PIC(library)->ft_outline_glyph_class) +#define FT_BITMAP_GLYPH_CLASS_GET (&GET_PIC(library)->ft_bitmap_glyph_class) +#define FT_DEFAULT_MODULES_GET (GET_PIC(library)->default_module_classes) + + void + ft_base_pic_free( FT_Library library ); + + FT_Error + ft_base_pic_init( FT_Library library ); + +#endif /* FT_CONFIG_OPTION_PIC */ + /* */ + +FT_END_HEADER + +#endif /* __BASEPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftadvanc.c b/lib/3rdparty/freetype/src/base/ftadvanc.c new file mode 100644 index 00000000000..8ab7fcb9271 --- /dev/null +++ b/lib/3rdparty/freetype/src/base/ftadvanc.c @@ -0,0 +1,163 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.c */ +/* */ +/* Quick computation of advance widths (body). */ +/* */ +/* Copyright 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_ADVANCES_H +#include FT_INTERNAL_OBJECTS_H + + + static FT_Error + _ft_face_scale_advances( FT_Face face, + FT_Fixed* advances, + FT_UInt count, + FT_Int32 flags ) + { + FT_Fixed scale; + FT_UInt nn; + + + if ( flags & FT_LOAD_NO_SCALE ) + return FT_Err_Ok; + + if ( face->size == NULL ) + return FT_Err_Invalid_Size_Handle; + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + scale = face->size->metrics.y_scale; + else + scale = face->size->metrics.x_scale; + + /* this must be the same scaling as to get linear{Hori,Vert}Advance */ + /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */ + + for ( nn = 0; nn < count; nn++ ) + advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); + + return FT_Err_Ok; + } + + + /* at the moment, we can perform fast advance retrieval only in */ + /* the following cases: */ + /* */ + /* - unscaled load */ + /* - unhinted load */ + /* - light-hinted load */ + +#define LOAD_ADVANCE_FAST_CHECK( flags ) \ + ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ + FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 flags, + FT_Fixed *padvance ) + { + FT_Face_GetAdvancesFunc func; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( gindex >= (FT_UInt)face->num_glyphs ) + return FT_Err_Invalid_Glyph_Index; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + FT_Error error; + + + error = func( face, gindex, 1, flags, padvance ); + if ( !error ) + return _ft_face_scale_advances( face, padvance, 1, flags ); + + if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) + return error; + } + + return FT_Get_Advances( face, gindex, 1, flags, padvance ); + } + + + /* documentation is in ftadvanc.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *padvances ) + { + FT_Face_GetAdvancesFunc func; + FT_UInt num, end, nn; + FT_Error error = FT_Err_Ok; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + num = (FT_UInt)face->num_glyphs; + end = start + count; + if ( start >= num || end < start || end > num ) + return FT_Err_Invalid_Glyph_Index; + + if ( count == 0 ) + return FT_Err_Ok; + + func = face->driver->clazz->get_advances; + if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + { + error = func( face, start, count, flags, padvances ); + if ( !error ) + goto Exit; + + if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) ) + return error; + } + + error = FT_Err_Ok; + + if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) + return FT_Err_Unimplemented_Feature; + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + for ( nn = 0; nn < count; nn++ ) + { + error = FT_Load_Glyph( face, start + nn, flags ); + if ( error ) + break; + + padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? face->glyph->advance.y + : face->glyph->advance.x; + } + + if ( error ) + return error; + + Exit: + return _ft_face_scale_advances( face, padvances, count, flags ); + } + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftbase.c b/lib/3rdparty/freetype/src/base/ftbase.c index d176b8150c3..6a27ea95a62 100644 --- a/lib/3rdparty/freetype/src/base/ftbase.c +++ b/lib/3rdparty/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,19 +20,22 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT +#include "ftpic.c" +#include "basepic.c" +#include "ftadvanc.c" #include "ftcalc.c" #include "ftdbgmem.c" #include "ftgloadr.c" -#include "ftnames.c" #include "ftobjs.c" #include "ftoutln.c" #include "ftrfork.c" +#include "ftsnames.c" #include "ftstream.c" #include "fttrigon.c" #include "ftutil.c" -#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) -#include <ftmac.c> +#if defined( FT_MACINTOSH ) && !defined ( DARWIN_NO_CARBON ) +#include "ftmac.c" #endif /* END */ diff --git a/lib/3rdparty/freetype/src/base/ftbase.h b/lib/3rdparty/freetype/src/base/ftbase.h new file mode 100644 index 00000000000..1dc49f3bdf6 --- /dev/null +++ b/lib/3rdparty/freetype/src/base/ftbase.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* ftbase.h */ +/* */ +/* The FreeType private functions used in base module (specification). */ +/* */ +/* Copyright 2008, 2010 by */ +/* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBASE_H__ +#define __FTBASE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */ + /* font, and try to load a face specified by the face_index. */ + FT_LOCAL( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ); + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* From ftmac.c. */ + FT_LOCAL( FT_Error ) + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ); + + +FT_END_HEADER + +#endif /* __FTBASE_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftbbox.c b/lib/3rdparty/freetype/src/base/ftbbox.c index 532ab135791..4b8e9112fee 100644 --- a/lib/3rdparty/freetype/src/base/ftbbox.c +++ b/lib/3rdparty/freetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ /* */ /* FreeType bbox computation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -29,6 +29,7 @@ #include FT_IMAGE_H #include FT_OUTLINE_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_OBJECTS_H typedef struct TBBox_Rec_ @@ -139,7 +140,7 @@ /* */ /* <Description> */ /* This function is used as a `conic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */ + /* FT_Outline_Decompose(). It checks a conic Bezier curve with the */ /* current bounding box, and computes its extrema if necessary to */ /* update it. */ /* */ @@ -506,7 +507,7 @@ /* */ /* <Description> */ /* This function is used as a `cubic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */ + /* FT_Outline_Decompose(). It checks a cubic Bezier curve with the */ /* current bounding box, and computes its extrema if necessary to */ /* update it. */ /* */ @@ -559,6 +560,13 @@ return 0; } +FT_DEFINE_OUTLINE_FUNCS(bbox_interface, + (FT_Outline_MoveTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_ConicTo_Func)BBox_Conic_To, + (FT_Outline_CubicTo_Func)BBox_Cubic_To, + 0, 0 + ) /* documentation is in ftbbox.h */ @@ -628,18 +636,13 @@ /* the two boxes are different, now walk over the outline to */ /* get the Bezier arc extrema. */ - static const FT_Outline_Funcs bbox_interface = - { - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 - }; - FT_Error error; TBBox_Rec user; +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs bbox_interface; + Init_Class_bbox_interface(&bbox_interface); +#endif user.bbox = bbox; diff --git a/lib/3rdparty/freetype/src/base/ftbitmap.c b/lib/3rdparty/freetype/src/base/ftbitmap.c index c847eb00d24..82b5baf2a64 100644 --- a/lib/3rdparty/freetype/src/base/ftbitmap.c +++ b/lib/3rdparty/freetype/src/base/ftbitmap.c @@ -2,10 +2,9 @@ /* */ /* ftbitmap.c */ /* */ -/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ -/* bitmaps into 8bpp format (body). */ +/* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +18,7 @@ #include <ft2build.h> #include FT_BITMAP_H +#include FT_IMAGE_H #include FT_INTERNAL_OBJECTS_H @@ -228,8 +228,12 @@ if ( !bitmap || !bitmap->buffer ) return FT_Err_Invalid_Argument; - xstr = FT_PIX_ROUND( xStrength ) >> 6; - ystr = FT_PIX_ROUND( yStrength ) >> 6; + if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) || + ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) ) + return FT_Err_Invalid_Argument; + + xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6; + ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6; if ( xstr == 0 && ystr == 0 ) return FT_Err_Ok; @@ -388,6 +392,8 @@ case FT_PIXEL_MODE_GRAY: case FT_PIXEL_MODE_GRAY2: case FT_PIXEL_MODE_GRAY4: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: { FT_Int pad; FT_Long old_size; @@ -482,6 +488,8 @@ case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_LCD: + case FT_PIXEL_MODE_LCD_V: { FT_Int width = source->width; FT_Byte* s = source->buffer; @@ -603,6 +611,31 @@ } + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) + { + if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && + !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_Bitmap bitmap; + FT_Error error; + + + FT_Bitmap_New( &bitmap ); + error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); + if ( error ) + return error; + + slot->bitmap = bitmap; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + } + + return FT_Err_Ok; + } + + /* documentation is in ftbitmap.h */ FT_EXPORT_DEF( FT_Error ) diff --git a/lib/3rdparty/freetype/src/base/ftcalc.c b/lib/3rdparty/freetype/src/base/ftcalc.c index 63aed95b75e..3892fabfe93 100644 --- a/lib/3rdparty/freetype/src/base/ftcalc.c +++ b/lib/3rdparty/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,10 +33,14 @@ #include <ft2build.h> +#include FT_GLYPH_H #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H +#ifdef FT_MULFIX_INLINED +#undef FT_MulFix +#endif /* we need to define a 64-bits data type here */ @@ -106,12 +110,12 @@ FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt32( FT_Int32 x ) { - FT_ULong val, root, newroot, mask; + FT_UInt32 val, root, newroot, mask; root = 0; - mask = 0x40000000L; - val = (FT_ULong)x; + mask = (FT_UInt32)0x40000000UL; + val = (FT_UInt32)x; do { @@ -192,15 +196,33 @@ FT_MulFix( FT_Long a, FT_Long b ) { +#ifdef FT_MULFIX_ASSEMBLER + + return FT_MULFIX_ASSEMBLER( a, b ); + +#else + FT_Int s = 1; FT_Long c; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } + if ( a < 0 ) + { + a = -a; + s = -1; + } + + if ( b < 0 ) + { + b = -b; + s = -s; + } c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); - return ( s > 0 ) ? c : -c ; + + return ( s > 0 ) ? c : -c; + +#endif /* FT_MULFIX_ASSEMBLER */ } @@ -340,6 +362,7 @@ long s; + /* XXX: this function does not allow 64-bit arguments */ if ( a == 0 || b == c ) return a; @@ -355,12 +378,12 @@ FT_Int64 temp, temp2; - ft_multo64( a, b, &temp ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); temp2.hi = 0; temp2.lo = (FT_UInt32)(c >> 1); FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -394,8 +417,8 @@ FT_Int64 temp; - ft_multo64( a, b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -412,31 +435,18 @@ FT_MulFix( FT_Long a, FT_Long b ) { - /* use inline assembly to speed up things a bit */ +#ifdef FT_MULFIX_ASSEMBLER -#if defined( __GNUC__ ) && defined( i386 ) + return FT_MULFIX_ASSEMBLER( a, b ); - FT_Long result; +#elif 0 - - __asm__ __volatile__ ( - "imul %%edx\n" - "movl %%edx, %%ecx\n" - "sarl $31, %%ecx\n" - "addl $0x8000, %%ecx\n" - "addl %%ecx, %%eax\n" - "adcl $0, %%edx\n" - "shrl $16, %%eax\n" - "shll $16, %%edx\n" - "addl %%edx, %%eax\n" - "mov %%eax, %0\n" - : "=r"(result) - : "a"(a), "d"(b) - : "%ecx" - ); - return result; - -#elif 1 + /* + * This code is nonportable. See comment below. + * + * However, on a platform where right-shift of a signed quantity fills + * the leftmost bits by copying the sign bit, it might be faster. + */ FT_Long sa, sb; FT_ULong ua, ub; @@ -445,6 +455,24 @@ if ( a == 0 || b == 0x10000L ) return a; + /* + * This is a clever way of converting a signed number `a' into its + * absolute value (stored back into `a') and its sign. The sign is + * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' + * was negative. (Similarly for `b' and `sb'). + * + * Unfortunately, it doesn't work (at least not portably). + * + * It makes the assumption that right-shift on a negative signed value + * fills the leftmost bits by copying the sign bit. This is wrong. + * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, + * the result of right-shift of a negative signed value is + * implementation-defined. At least one implementation fills the + * leftmost bits with 0s (i.e., it is exactly the same as an unsigned + * right shift). This means that when `a' is negative, `sa' ends up + * with the value 1 rather than -1. After that, everything else goes + * wrong. + */ sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); a = ( a ^ sa ) - sa; sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); @@ -512,13 +540,14 @@ FT_UInt32 q; - s = a; a = FT_ABS(a); - s ^= b; b = FT_ABS(b); + /* XXX: this function does not allow 64-bit arguments */ + s = (FT_Int32)a; a = FT_ABS( a ); + s ^= (FT_Int32)b; b = FT_ABS( b ); if ( b == 0 ) { /* check for division by 0 */ - q = 0x7FFFFFFFL; + q = (FT_UInt32)0x7FFFFFFFL; } else if ( ( a >> 16 ) == 0 ) { @@ -535,7 +564,7 @@ temp2.hi = 0; temp2.lo = (FT_UInt32)( b >> 1 ); FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, b ); + q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); } return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); @@ -666,6 +695,110 @@ #endif /* FT_LONG64 */ + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix *b ) + { + FT_Fixed xx, xy, yx, yy; + + + if ( !a || !b ) + return; + + xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); + xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); + yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); + yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ) + { + FT_Pos delta, xx, yy; + + + if ( !matrix ) + return FT_Err_Invalid_Argument; + + /* compute discriminant */ + delta = FT_MulFix( matrix->xx, matrix->yy ) - + FT_MulFix( matrix->xy, matrix->yx ); + + if ( !delta ) + return FT_Err_Invalid_Argument; /* matrix can't be inverted */ + + matrix->xy = - FT_DivFix( matrix->xy, delta ); + matrix->yx = - FT_DivFix( matrix->yx, delta ); + + xx = matrix->xx; + yy = matrix->yy; + + matrix->xx = FT_DivFix( yy, delta ); + matrix->yy = FT_DivFix( xx, delta ); + + return FT_Err_Ok; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ) + { + FT_Fixed xx, xy, yx, yy; + + FT_Long val = 0x10000L * scaling; + + + if ( !a || !b ) + return; + + xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); + xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); + yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); + yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ) + { + FT_Pos xz, yz; + + FT_Long val = 0x10000L * scaling; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulDiv( vector->x, matrix->xx, val ) + + FT_MulDiv( vector->y, matrix->xy, val ); + + yz = FT_MulDiv( vector->x, matrix->yx, val ) + + FT_MulDiv( vector->y, matrix->yy, val ); + + vector->x = xz; + vector->y = yz; + } + + /* documentation is in ftcalc.h */ FT_BASE_DEF( FT_Int32 ) @@ -709,7 +842,7 @@ FT_Pos out_x, FT_Pos out_y ) { - FT_Int result; + FT_Long result; /* avoid overflow on 16-bit system */ /* deal with the trivial cases quickly */ @@ -758,8 +891,9 @@ FT_Int64 z1, z2; - ft_multo64( in_x, out_y, &z1 ); - ft_multo64( in_y, out_x, &z2 ); + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); + ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); if ( z1.hi > z2.hi ) result = +1; @@ -775,7 +909,8 @@ #endif } - return result; + /* XXX: only the sign of return value, +1/0/-1 must be used */ + return (FT_Int)result; } diff --git a/lib/3rdparty/freetype/src/base/ftcid.c b/lib/3rdparty/freetype/src/base/ftcid.c new file mode 100644 index 00000000000..733aae14751 --- /dev/null +++ b/lib/3rdparty/freetype/src/base/ftcid.c @@ -0,0 +1,117 @@ +/***************************************************************************/ +/* */ +/* ftcid.c */ +/* */ +/* FreeType API for accessing CID font information. */ +/* */ +/* Copyright 2007, 2009 by Derek Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CID_H +#include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_CID_H + + + /* documentation is in ftcid.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement) + { + FT_Error error; + const char* r = NULL; + const char* o = NULL; + FT_Int s = 0; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_ros ) + error = service->get_ros( face, &r, &o, &s ); + } + + if ( registry ) + *registry = r; + + if ( ordering ) + *ordering = o; + + if ( supplement ) + *supplement = s; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Bool ic = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_is_cid ) + error = service->get_is_cid( face, &ic); + } + + if ( is_cid ) + *is_cid = ic; + + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_UInt c = 0; + + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_cid_from_glyph_index ) + error = service->get_cid_from_glyph_index( face, glyph_index, &c); + } + + if ( cid ) + *cid = c; + + return error; + } + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftdbgmem.c b/lib/3rdparty/freetype/src/base/ftdbgmem.c index 52a5c2057f8..160269d1929 100644 --- a/lib/3rdparty/freetype/src/base/ftdbgmem.c +++ b/lib/3rdparty/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,8 +33,7 @@ * memory, however. */ -#include <stdio.h> -#include <stdlib.h> +#include FT_CONFIG_STANDARD_LIBRARY_H FT_BASE_DEF( const char* ) _ft_debug_file = 0; FT_BASE_DEF( long ) _ft_debug_lineno = 0; @@ -422,7 +421,7 @@ "FreeType: %ld bytes of memory leaked in %ld blocks\n", leaks, leak_count ); - printf( "FreeType: No memory leaks detected!\n" ); + printf( "FreeType: no memory leaks detected\n" ); } } @@ -990,7 +989,7 @@ #else /* !FT_DEBUG_MEMORY */ /* ANSI C doesn't like empty source files */ - const FT_Byte _debug_mem_dummy = 0; + typedef int _debug_mem_dummy; #endif /* !FT_DEBUG_MEMORY */ diff --git a/lib/3rdparty/freetype/src/base/ftdebug.c b/lib/3rdparty/freetype/src/base/ftdebug.c index c55d3c8114e..2adbeabeb23 100644 --- a/lib/3rdparty/freetype/src/base/ftdebug.c +++ b/lib/3rdparty/freetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004 by */ +/* Copyright 1996-2001, 2002, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,7 +46,7 @@ #include FT_INTERNAL_DEBUG_H -#if defined( FT_DEBUG_LEVEL_ERROR ) +#ifdef FT_DEBUG_LEVEL_ERROR /* documentation is in ftdebug.h */ @@ -57,7 +57,7 @@ va_start( ap, fmt ); - vprintf( fmt, ap ); + vfprintf( stderr, fmt, ap ); va_end( ap ); } @@ -71,7 +71,7 @@ va_start( ap, fmt ); - vprintf( fmt, ap ); + vfprintf( stderr, fmt, ap ); va_end( ap ); exit( EXIT_FAILURE ); diff --git a/lib/3rdparty/freetype/src/base/ftfstype.c b/lib/3rdparty/freetype/src/base/ftfstype.c new file mode 100644 index 00000000000..d0ef7b7c1b0 --- /dev/null +++ b/lib/3rdparty/freetype/src/base/ftfstype.c @@ -0,0 +1,62 @@ +/***************************************************************************/ +/* */ +/* ftfstype.c */ +/* */ +/* FreeType utility file to access FSType data (body). */ +/* */ +/* Copyright 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ) + { + TT_OS2* os2; + + + /* first, try to get the fs_type directly from the font */ + if ( face ) + { + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_extra ) + { + PS_FontExtraRec extra; + + + if ( !service->ps_get_font_extra( face, &extra ) && + extra.fs_type != 0 ) + return extra.fs_type; + } + } + + /* look at FSType before fsType for Type42 */ + + if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL && + os2->version != 0xFFFFU ) + return os2->fsType; + + return 0; + } + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftgloadr.c b/lib/3rdparty/freetype/src/base/ftgloadr.c index ab52621ea67..ac0010ddd88 100644 --- a/lib/3rdparty/freetype/src/base/ftgloadr.c +++ b/lib/3rdparty/freetype/src/base/ftgloadr.c @@ -218,6 +218,9 @@ { new_max = FT_PAD_CEIL( new_max, 8 ); + if ( new_max > FT_OUTLINE_POINTS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) goto Exit; @@ -246,6 +249,10 @@ if ( new_max > old_max ) { new_max = FT_PAD_CEIL( new_max, 4 ); + + if ( new_max > FT_OUTLINE_CONTOURS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) goto Exit; diff --git a/lib/3rdparty/freetype/src/base/ftglyph.c b/lib/3rdparty/freetype/src/base/ftglyph.c index 969c5dbb05a..3505d6dde9a 100644 --- a/lib/3rdparty/freetype/src/base/ftglyph.c +++ b/lib/3rdparty/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,6 +34,7 @@ #include FT_BITMAP_H #include FT_INTERNAL_OBJECTS_H +#include "basepic.h" /*************************************************************************/ /* */ @@ -45,68 +46,6 @@ #define FT_COMPONENT trace_glyph - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** Convenience functions ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix *b ) - { - FT_Fixed xx, xy, yx, yy; - - - if ( !a || !b ) - return; - - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Matrix_Invert( FT_Matrix* matrix ) - { - FT_Pos delta, xx, yy; - - - if ( !matrix ) - return FT_Err_Invalid_Argument; - - /* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - - if ( !delta ) - return FT_Err_Invalid_Argument; /* matrix can't be inverted */ - - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); - - xx = matrix->xx; - yy = matrix->yy; - - matrix->xx = FT_DivFix( yy, delta ); - matrix->yy = FT_DivFix( xx, delta ); - - return FT_Err_Ok; - } - - /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -191,9 +130,7 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_bitmap_glyph_class = - { + FT_DEFINE_GLYPH(ft_bitmap_glyph_class, sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, @@ -203,7 +140,7 @@ 0, /* FT_Glyph_TransformFunc */ ft_bitmap_glyph_bbox, 0 /* FT_Glyph_PrepareFunc */ - }; + ) /*************************************************************************/ @@ -317,9 +254,7 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_outline_glyph_class = - { + FT_DEFINE_GLYPH( ft_outline_glyph_class, sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, @@ -329,7 +264,7 @@ ft_outline_glyph_transform, ft_outline_glyph_bbox, ft_outline_glyph_prepare - }; + ) /*************************************************************************/ @@ -376,10 +311,16 @@ const FT_Glyph_Class* clazz; + /* check arguments */ + if ( !target ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + *target = 0; - /* check arguments */ - if ( !target || !source || !source->clazz ) + if ( !source || !source->clazz ) { error = FT_Err_Invalid_Argument; goto Exit; @@ -429,11 +370,11 @@ /* if it is a bitmap, that's easy :-) */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - clazz = &ft_bitmap_glyph_class; + clazz = FT_BITMAP_GLYPH_CLASS_GET; - /* it it is an outline too */ + /* if it is an outline */ else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - clazz = &ft_outline_glyph_class; + clazz = FT_OUTLINE_GLYPH_CLASS_GET; else { @@ -574,6 +515,10 @@ const FT_Glyph_Class* clazz; +#ifdef FT_CONFIG_OPTION_PIC + FT_Library library = FT_GLYPH( glyph )->library; +#endif + /* check argument */ if ( !the_glyph ) @@ -589,7 +534,7 @@ clazz = glyph->clazz; /* when called with a bitmap glyph, do nothing and return successfully */ - if ( clazz == &ft_bitmap_glyph_class ) + if ( clazz == FT_BITMAP_GLYPH_CLASS_GET ) goto Exit; if ( !clazz || !clazz->glyph_prepare ) @@ -602,7 +547,7 @@ dummy.format = clazz->glyph_format; /* create result bitmap glyph */ - error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, + error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET, (FT_Glyph*)(void*)&bitmap ); if ( error ) goto Exit; diff --git a/lib/3rdparty/freetype/src/base/ftinit.c b/lib/3rdparty/freetype/src/base/ftinit.c index 7af19c3d80f..f94f25a83c1 100644 --- a/lib/3rdparty/freetype/src/base/ftinit.c +++ b/lib/3rdparty/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,7 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_MODULE_H +#include "basepic.h" /*************************************************************************/ @@ -53,11 +54,13 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_init +#ifndef FT_CONFIG_OPTION_PIC + #undef FT_USE_MODULE #ifdef __cplusplus -#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class x; +#define FT_USE_MODULE( type, x ) extern "C" const type x; #else -#define FT_USE_MODULE( x ) extern const FT_Module_Class x; +#define FT_USE_MODULE( type, x ) extern const type x; #endif @@ -65,7 +68,7 @@ #undef FT_USE_MODULE -#define FT_USE_MODULE( x ) (const FT_Module_Class*)&(x), +#define FT_USE_MODULE( type, x ) (const FT_Module_Class*)&(x), static const FT_Module_Class* const ft_default_modules[] = @@ -74,6 +77,99 @@ 0 }; +#else /* FT_CONFIG_OPTION_PIC */ + +#ifdef __cplusplus +#define FT_EXTERNC extern "C" +#else +#define FT_EXTERNC extern +#endif + + /* declare the module's class creation/destruction functions */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + FT_EXTERNC FT_Error FT_Create_Class_##x( FT_Library library, FT_Module_Class** output_class ); \ + FT_EXTERNC void FT_Destroy_Class_##x( FT_Library library, FT_Module_Class* clazz ); + +#include FT_CONFIG_MODULES_H + + + /* count all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) MODULE_CLASS_##x, + + enum { +#include FT_CONFIG_MODULES_H + FT_NUM_MODULE_CLASSES + }; + + /* destroy all module classes */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + if ( classes[i] ) { FT_Destroy_Class_##x(library, classes[i]); } \ + i++; \ + + FT_BASE_DEF( void ) + ft_destroy_default_module_classes( FT_Library library ) + { + FT_Module_Class** classes; + FT_Memory memory; + FT_UInt i; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; + + if ( !pic_container->default_module_classes ) + return; + + memory = library->memory; + classes = pic_container->default_module_classes; + i = 0; + +#include FT_CONFIG_MODULES_H + + FT_FREE( classes ); + pic_container->default_module_classes = 0; + } + + /* initialize all module classes and the pointer table */ +#undef FT_USE_MODULE +#define FT_USE_MODULE( type, x ) \ + error = FT_Create_Class_##x(library, &clazz); \ + if (error) goto Exit; \ + classes[i++] = clazz; + + FT_BASE_DEF( FT_Error ) + ft_create_default_module_classes( FT_Library library ) + { + FT_Error error; + FT_Memory memory; + FT_Module_Class** classes; + FT_Module_Class* clazz; + FT_UInt i; + BasePIC* pic_container = (BasePIC*)library->pic_container.base; + + memory = library->memory; + pic_container->default_module_classes = 0; + + if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) ) + return error; + /* initialize all pointers to 0, especially the last one */ + for (i = 0; i < FT_NUM_MODULE_CLASSES; i++) + classes[i] = 0; + classes[FT_NUM_MODULE_CLASSES] = 0; + + i = 0; + +#include FT_CONFIG_MODULES_H + +Exit: + if (error) ft_destroy_default_module_classes( library ); + else pic_container->default_module_classes = classes; + + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ /* documentation is in ftmodapi.h */ @@ -86,16 +182,15 @@ /* test for valid `library' delayed to FT_Add_Module() */ - cur = ft_default_modules; + cur = FT_DEFAULT_MODULES_GET; while ( *cur ) { error = FT_Add_Module( library, *cur ); /* notify errors, but don't stop */ if ( error ) - { - FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = 0x%x\n", - (*cur)->module_name, error )); - } + FT_TRACE0(( "FT_Add_Default_Module:" + " Cannot install `%s', error = 0x%x\n", + (*cur)->module_name, error )); cur++; } } @@ -127,13 +222,7 @@ if ( error ) FT_Done_Memory( memory ); else - { - (*alibrary)->version_major = FREETYPE_MAJOR; - (*alibrary)->version_minor = FREETYPE_MINOR; - (*alibrary)->version_patch = FREETYPE_PATCH; - FT_Add_Default_Modules( *alibrary ); - } return error; } diff --git a/lib/3rdparty/freetype/src/base/ftlcdfil.c b/lib/3rdparty/freetype/src/base/ftlcdfil.c index f40bbeae5fb..80640111c4f 100644 --- a/lib/3rdparty/freetype/src/base/ftlcdfil.c +++ b/lib/3rdparty/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -161,7 +161,7 @@ #ifdef USE_LEGACY - /* FIR filter used by the default and light filters */ + /* intra-pixel filter used by the legacy filter */ static void _ft_lcd_filter_legacy( FT_Bitmap* bitmap, FT_Render_Mode mode, @@ -181,7 +181,7 @@ FT_UNUSED( library ); - /* horizontal in-place FIR filter */ + /* horizontal in-place intra-pixel filter */ if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) { FT_Byte* line = bitmap->buffer; @@ -266,7 +266,7 @@ #endif /* USE_LEGACY */ - FT_EXPORT( FT_Error ) + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { @@ -296,13 +296,13 @@ #elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - memcpy( library->lcd_weights, light_filter, 5 ); + ft_memcpy( library->lcd_weights, light_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; #else - memcpy( library->lcd_weights, default_filter, 5 ); + ft_memcpy( library->lcd_weights, default_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; @@ -311,7 +311,7 @@ break; case FT_LCD_FILTER_LIGHT: - memcpy( library->lcd_weights, light_filter, 5 ); + ft_memcpy( library->lcd_weights, light_filter, 5 ); library->lcd_filter_func = _ft_lcd_filter_fir; library->lcd_extra = 2; break; @@ -335,7 +335,7 @@ #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - FT_EXPORT( FT_Error ) + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { diff --git a/lib/3rdparty/freetype/src/base/ftmac.c b/lib/3rdparty/freetype/src/base/ftmac.c index fd6201adb5a..63f927d57d8 100644 --- a/lib/3rdparty/freetype/src/base/ftmac.c +++ b/lib/3rdparty/freetype/src/base/ftmac.c @@ -8,7 +8,8 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, */ +/* 2009 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +68,9 @@ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_STREAM_H +#include "ftbase.h" /* This is for Mac OS X. Without redefinition, OS_INLINE */ /* expands to `static inline' which doesn't survive the */ @@ -76,20 +79,36 @@ #undef OS_INLINE #define OS_INLINE static __inline__ #endif -#include <Carbon/Carbon.h> -#ifndef HFS_MAXPATHLEN -#define HFS_MAXPATHLEN 1024 + /* `configure' checks the availability of `ResourceIndex' strictly */ + /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always. If it is */ + /* not set (e.g., a build without `configure'), the availability */ + /* is guessed from the SDK version. */ +#ifndef HAVE_TYPE_RESOURCE_INDEX +#if !defined( MAC_OS_X_VERSION_10_5 ) || \ + ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 ) +#define HAVE_TYPE_RESOURCE_INDEX 0 +#else +#define HAVE_TYPE_RESOURCE_INDEX 1 +#endif +#endif /* !HAVE_TYPE_RESOURCE_INDEX */ + +#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) + typedef short ResourceIndex; #endif +#include <CoreServices/CoreServices.h> +#include <ApplicationServices/ApplicationServices.h> +#include <sys/syslimits.h> /* PATH_MAX */ + + /* Don't want warnings about our own use of deprecated functions. */ #define FT_DEPRECATED_ATTRIBUTE #include FT_MAC_H - /* undefine blocking-macros in ftmac.h */ -#undef FT_GetFile_From_Mac_Name( a, b, c ) -#undef FT_GetFile_From_Mac_ATS_Name( a, b, c ) -#undef FT_New_Face_From_FSSpec( a, b, c, d ) +#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ +#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault +#endif /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over @@ -100,6 +119,7 @@ #endif + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, @@ -115,19 +135,28 @@ /* Private function. */ /* The FSSpec type has been discouraged for a long time, */ - /* but for some reason, there is no FSRef version of */ - /* ATSFontGetFileSpecification(), so we made our own. */ - /* Apple will provide one eventually. */ + /* unfortunately an FSRef replacement API for */ + /* ATSFontGetFileSpecification() is only available in */ + /* Mac OS X 10.5 and later. */ static OSStatus FT_ATSFontGetFileReference( ATSFontRef ats_font_id, FSRef* ats_font_ref ) { -#if __LP64__ +#if defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) + + OSStatus err; + + err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); + + return err; +#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ FT_UNUSED( ats_font_id ); FT_UNUSED( ats_font_ref ); + return fnfErr; -#else +#else /* 32bit Carbon API on legacy platforms */ OSStatus err; FSSpec spec; @@ -214,7 +243,8 @@ FSSpec* pathSpec, FT_Long* face_index ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) FT_UNUSED( fontName ); FT_UNUSED( pathSpec ); FT_UNUSED( face_index ); @@ -239,8 +269,8 @@ static OSErr - FT_FSPathMakeRes( const UInt8* pathname, - short* res ) + FT_FSPathMakeRes( const UInt8* pathname, + ResFileRefNum* res ) { OSErr err; FSRef ref; @@ -357,7 +387,7 @@ static void parse_fond( char* fond_data, short* have_sfnt, - short* sfnt_id, + ResID* sfnt_id, Str255 lwfn_file_name, short face_index ) { @@ -374,6 +404,10 @@ assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; + /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ + if ( 47 < face_index ) + return; + /* Let's do a little range checking before we get too excited here */ if ( face_index < count_faces_sfnt( fond_data ) ) { @@ -425,9 +459,10 @@ ft_memcpy(ps_name, names[0] + 1, ps_name_len); ps_name[ps_name_len] = 0; } - if ( style->indexes[0] > 1 ) + if ( style->indexes[face_index] > 1 && + style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) { - unsigned char* suffixes = names[style->indexes[0] - 1]; + unsigned char* suffixes = names[style->indexes[face_index] - 1]; for ( i = 1; i <= suffixes[0]; i++ ) @@ -463,8 +498,8 @@ UInt8* path_lwfn, size_t path_size ) { - FSRef ref, par_ref; - int dirname_len; + FSRef ref, par_ref; + size_t dirname_len; /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ @@ -504,10 +539,10 @@ count_faces( Handle fond, const UInt8* pathname ) { - short sfnt_id; + ResID sfnt_id; short have_sfnt, have_lwfn; Str255 lwfn_file_name; - UInt8 buff[HFS_MAXPATHLEN]; + UInt8 buff[PATH_MAX]; FT_Error err; short num_faces; @@ -539,13 +574,13 @@ chunks are often not organized that way, so we glue chunks of the same type together. */ static FT_Error - read_lwfn( FT_Memory memory, - short res, - FT_Byte** pfb_data, - FT_ULong* size ) + read_lwfn( FT_Memory memory, + ResFileRefNum res, + FT_Byte** pfb_data, + FT_ULong* size ) { FT_Error error = FT_Err_Ok; - short res_id; + ResID res_id; unsigned char *buffer, *p, *size_p = NULL; FT_ULong total_size = 0; FT_ULong old_total_size = 0; @@ -563,7 +598,7 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( TTAG_POST, res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -602,7 +637,7 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( TTAG_POST, res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -654,120 +689,17 @@ } - /* Finalizer for a memory stream; gets called by FT_Done_Face(). - It frees the memory it uses. */ - static void - memory_stream_close( FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - FT_FREE( stream->base ); - - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Create a new memory stream from a buffer and a size. */ - static FT_Error - new_memory_stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream_CloseFunc close, - FT_Stream* astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !base ) - return FT_Err_Invalid_Argument; - - *astream = 0; - memory = library->memory; - if ( FT_NEW( stream ) ) - goto Exit; - - FT_Stream_OpenMemory( stream, base, size ); - - stream->close = close; - - *astream = stream; - - Exit: - return error; - } - - - /* Create a new FT_Face given a buffer and a driver name. */ - static FT_Error - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - char* driver_name, - FT_Face* aface ) - { - FT_Open_Args args; - FT_Error error; - FT_Stream stream; - FT_Memory memory = library->memory; - - - error = new_memory_stream( library, - base, - size, - memory_stream_close, - &stream ); - if ( error ) - { - FT_FREE( base ); - return error; - } - - args.flags = FT_OPEN_STREAM; - args.stream = stream; - if ( driver_name ) - { - args.flags = args.flags | FT_OPEN_DRIVER; - args.driver = FT_Get_Module( library, driver_name ); - } - - /* At this point, face_index has served its purpose; */ - /* whoever calls this function has already used it to */ - /* locate the correct font data. We should not propagate */ - /* this index to FT_Open_Face() (unless it is negative). */ - - if ( face_index > 0 ) - face_index = 0; - - error = FT_Open_Face( library, &args, face_index, aface ); - if ( error == FT_Err_Ok ) - (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - else - FT_Stream_Free( stream, 0 ); - - return error; - } - - - /* Create a new FT_Face from a file spec to an LWFN file. */ + /* Create a new FT_Face from a file path to an LWFN file. */ static FT_Error FT_New_Face_From_LWFN( FT_Library library, const UInt8* pathname, FT_Long face_index, FT_Face* aface ) { - FT_Byte* pfb_data; - FT_ULong pfb_size; - FT_Error error; - short res; + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + ResFileRefNum res; if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) @@ -792,7 +724,7 @@ /* Create a new FT_Face from an SFNT resource, specified by res ID. */ static FT_Error FT_New_Face_From_SFNT( FT_Library library, - short sfnt_id, + ResID sfnt_id, FT_Long face_index, FT_Face* aface ) { @@ -801,11 +733,11 @@ size_t sfnt_size; FT_Error error = FT_Err_Ok; FT_Memory memory = library->memory; - int is_cff; + int is_cff, is_sfnt_ps; - sfnt = GetResource( 'sfnt', sfnt_id ); - if ( ResError() ) + sfnt = GetResource( TTAG_sfnt, sfnt_id ); + if ( sfnt == NULL ) return FT_Err_Invalid_Handle; sfnt_size = (FT_ULong)GetHandleSize( sfnt ); @@ -818,31 +750,56 @@ ft_memcpy( sfnt_data, *sfnt, sfnt_size ); ReleaseResource( sfnt ); - is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; + is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); - return open_face_from_buffer( library, - sfnt_data, - sfnt_size, - face_index, - is_cff ? "cff" : "truetype", - aface ); + if ( is_sfnt_ps ) + { + FT_Stream stream; + + + if ( FT_NEW( stream ) ) + goto Try_OpenType; + + FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size ); + if ( !open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ) ) + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + FT_FREE( sfnt_data ); + goto Exit; + } + + FT_FREE( stream ); + } + Try_OpenType: + error = open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + is_cff ? "cff" : "truetype", + aface ); + Exit: + return error; } - /* Create a new FT_Face from a file spec to a suitcase file. */ + /* Create a new FT_Face from a file path to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, const UInt8* pathname, FT_Long face_index, FT_Face* aface ) { - FT_Error error = FT_Err_Cannot_Open_Resource; - short res_ref, res_index; - Handle fond; - short num_faces_in_res, num_faces_in_fond; + FT_Error error = FT_Err_Cannot_Open_Resource; + ResFileRefNum res_ref; + ResourceIndex res_index; + Handle fond; + short num_faces_in_res, num_faces_in_fond; if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) @@ -855,7 +812,7 @@ num_faces_in_res = 0; for ( res_index = 1; ; ++res_index ) { - fond = Get1IndResource( 'FOND', res_index ); + fond = Get1IndResource( TTAG_FOND, res_index ); if ( ResError() ) break; @@ -869,7 +826,7 @@ } CloseResFile( res_ref ); - if ( FT_Err_Ok == error && NULL != aface ) + if ( FT_Err_Ok == error && NULL != aface && NULL != *aface ) (*aface)->num_faces = num_faces_in_res; return error; } @@ -883,25 +840,25 @@ FT_Long face_index, FT_Face* aface ) { - short sfnt_id, have_sfnt, have_lwfn = 0; - short fond_id; + short have_sfnt, have_lwfn = 0; + ResID sfnt_id, fond_id; OSType fond_type; Str255 fond_name; Str255 lwfn_file_name; - UInt8 path_lwfn[HFS_MAXPATHLEN]; + UInt8 path_lwfn[PATH_MAX]; OSErr err; FT_Error error = FT_Err_Ok; GetResInfo( fond, &fond_id, &fond_type, fond_name ); - if ( ResError() != noErr || fond_type != 'FOND' ) + if ( ResError() != noErr || fond_type != TTAG_FOND ) return FT_Err_Invalid_File_Format; parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); if ( lwfn_file_name[0] ) { - short res; + ResFileRefNum res; res = HomeResFile( fond ); @@ -909,7 +866,7 @@ goto found_no_lwfn_file; { - UInt8 path_fond[HFS_MAXPATHLEN]; + UInt8 path_fond[PATH_MAX]; FSRef ref; @@ -961,7 +918,7 @@ /* LWFN is a (very) specific file format, check for it explicitly */ file_type = get_file_type_from_path( pathname ); - if ( file_type == 'LWFN' ) + if ( file_type == TTAG_LWFN ) return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); /* Otherwise the file type doesn't matter (there are more than */ @@ -1029,6 +986,8 @@ /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ /* accepts an FSRef instead of a path. */ /* */ + /* This function is deprecated because Carbon data types (FSRef) */ + /* are not cross-platform, and thus not suitable for the freetype API. */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, @@ -1038,7 +997,7 @@ FT_Error error; FT_Open_Args args; OSErr err; - UInt8 pathname[HFS_MAXPATHLEN]; + UInt8 pathname[PATH_MAX]; if ( !ref ) @@ -1068,13 +1027,15 @@ /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ /* accepts an FSSpec instead of a path. */ /* */ + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec* spec, FT_Long face_index, FT_Face* aface ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) FT_UNUSED( library ); FT_UNUSED( spec ); FT_UNUSED( face_index ); diff --git a/lib/3rdparty/freetype/src/base/ftmm.c b/lib/3rdparty/freetype/src/base/ftmm.c index 586d5e84db1..0307729811f 100644 --- a/lib/3rdparty/freetype/src/base/ftmm.c +++ b/lib/3rdparty/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2001, 2003, 2004 by */ +/* Copyright 1996-2001, 2003, 2004, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ *aservice, MULTI_MASTERS ); - if ( aservice ) + if ( *aservice ) error = FT_Err_Ok; } diff --git a/lib/3rdparty/freetype/src/base/ftobjs.c b/lib/3rdparty/freetype/src/base/ftobjs.c index fa080940045..46bcd3bb8b2 100644 --- a/lib/3rdparty/freetype/src/base/ftobjs.c +++ b/lib/3rdparty/freetype/src/base/ftobjs.c @@ -4,7 +4,8 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +27,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ #include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_IDS_H #include FT_OUTLINE_H @@ -36,8 +38,13 @@ #include FT_SERVICE_KERNING_H #include FT_SERVICE_TRUETYPE_ENGINE_H +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#include "ftbase.h" +#endif + #define GRID_FIT_METRICS + FT_BASE_DEF( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ) @@ -128,13 +135,14 @@ FT_Stream stream; + *astream = 0; + if ( !library ) return FT_Err_Invalid_Library_Handle; if ( !args ) return FT_Err_Invalid_Argument; - *astream = 0; memory = library->memory; if ( FT_NEW( stream ) ) @@ -196,6 +204,12 @@ } + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ #undef FT_COMPONENT #define FT_COMPONENT trace_objs @@ -244,7 +258,7 @@ FT_BASE_DEF( void ) ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) { - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); @@ -337,14 +351,18 @@ /* free bitmap buffer if needed */ ft_glyphslot_free_bitmap( slot ); - /* free glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) + /* slot->internal might be NULL in out-of-memory situations */ + if ( slot->internal ) { - FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; - } + /* free glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + FT_GlyphLoader_Done( slot->internal->loader ); + slot->internal->loader = 0; + } - FT_FREE( slot->internal ); + FT_FREE( slot->internal ); + } } @@ -542,7 +560,7 @@ FT_Driver driver; FT_GlyphSlot slot; FT_Library library; - FT_Bool autohint = 0; + FT_Bool autohint = FALSE; FT_Module hinter; @@ -577,31 +595,33 @@ * Determine whether we need to auto-hint or not. * The general rules are: * - * - Do only auto-hinting if we have a hinter module, - * a scalable font format dealing with outlines, - * and no transforms except simple slants. + * - Do only auto-hinting if we have a hinter module, a scalable font + * format dealing with outlines, and no transforms except simple + * slants and/or rotations by integer multiples of 90 degrees. * - * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set - * or if we don't have a native font hinter. + * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't + * have a native font hinter. * * - Otherwise, auto-hint for LIGHT hinting mode. * - * - Exception: The font requires the unpatented - * bytecode interpreter to load properly. + * - Exception: The font is `tricky' and requires the native hinter to + * load properly. */ - autohint = 0; - if ( hinter && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 && - ( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) && - face->internal->transform_matrix.yy > 0 && - face->internal->transform_matrix.yx == 0 ) + if ( hinter && + !( load_flags & FT_LOAD_NO_HINTING ) && + !( load_flags & FT_LOAD_NO_AUTOHINT ) && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) && + !FT_IS_TRICKY( face ) && + ( ( face->internal->transform_matrix.yx == 0 && + face->internal->transform_matrix.xx != 0 ) || + ( face->internal->transform_matrix.xx == 0 && + face->internal->transform_matrix.yx != 0 ) ) ) { - if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 || - !FT_DRIVER_HAS_HINTER( driver ) ) - autohint = 1; + if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) || + !FT_DRIVER_HAS_HINTER( driver ) ) + autohint = TRUE; else { FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); @@ -609,7 +629,7 @@ if ( mode == FT_RENDER_MODE_LIGHT || face->internal->ignore_unpatented_hinter ) - autohint = 1; + autohint = TRUE; } } @@ -634,12 +654,24 @@ goto Load_Ok; } - /* load auto-hinted outline */ - hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + { + FT_Face_Internal internal = face->internal; + FT_Int transform_flags = internal->transform_flags; - error = hinting->load_glyph( (FT_AutoHinter)hinter, - slot, face->size, - glyph_index, load_flags ); + + /* since the auto-hinter calls FT_Load_Glyph by itself, */ + /* make sure that glyphs aren't transformed */ + internal->transform_flags = 0; + + /* load auto-hinted outline */ + hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + + error = hinting->load_glyph( (FT_AutoHinter)hinter, + slot, face->size, + glyph_index, load_flags ); + + internal->transform_flags = transform_flags; + } } else { @@ -679,8 +711,8 @@ } /* compute the linear advance in 16.16 pixels */ - if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && + ( FT_IS_SCALABLE( face ) ) ) { FT_Size_Metrics* metrics = &face->size->metrics; @@ -710,11 +742,30 @@ renderer, slot, &internal->transform_matrix, &internal->transform_delta ); + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* apply `standard' transformation if no renderer is available */ + if ( &internal->transform_matrix ) + FT_Outline_Transform( &slot->outline, + &internal->transform_matrix ); + + if ( &internal->transform_delta ) + FT_Outline_Translate( &slot->outline, + internal->transform_delta.x, + internal->transform_delta.y ); + } + /* transform advance */ FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); } } + FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); + FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); + + FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); + FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); + /* do we need to render the image now? */ if ( !error && slot->format != FT_GLYPH_FORMAT_BITMAP && @@ -883,14 +934,13 @@ /* are limited to the BMP (said UCS-2 encoding.) */ /* */ /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE). */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ /* */ static FT_Error find_unicode_charmap( FT_Face face ) { FT_CharMap* first; FT_CharMap* cur; - FT_CharMap* unicmap = NULL; /* some UCS-2 map, if we found it */ /* caller should have already checked that `face' is valid */ @@ -935,36 +985,75 @@ { if ( cur[0]->encoding == FT_ENCODING_UNICODE ) { - unicmap = cur; /* record we found a Unicode charmap */ - - /* XXX If some new encodings to represent UCS-4 are added, */ - /* they should be added here. */ + /* XXX If some new encodings to represent UCS-4 are added, */ + /* they should be added here. */ if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - - /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) { face->charmap = cur[0]; - return 0; + return FT_Err_Ok; } } } - /* We do not have any UCS-4 charmap. Sigh. */ - /* Let's see if we have some other kind of Unicode charmap, though. */ - if ( unicmap != NULL ) + /* We do not have any UCS-4 charmap. */ + /* Do the loop again and search for UCS-2 charmaps. */ + cur = first + face->num_charmaps; + + for ( ; --cur >= first; ) { - face->charmap = unicmap[0]; - return 0; + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + face->charmap = cur[0]; + return FT_Err_Ok; + } } - /* Chou blanc! */ return FT_Err_Invalid_CharMap_Handle; } + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_variant_selector_charmap */ + /* */ + /* <Description> */ + /* This function finds the variant selector charmap, if there is one. */ + /* There can only be one (platform=0, specific=5, format=14). */ + /* */ + static FT_CharMap + find_variant_selector_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* end; + FT_CharMap* cur; + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT( face ); + + first = face->charmaps; + + if ( !first ) + return NULL; + + end = first + face->num_charmaps; /* points after the last one */ + + for ( cur = first; cur < end; ++cur ) + { + if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && + FT_Get_CMap_Format( cur[0] ) == 14 ) + return cur[0]; + } + + return NULL; + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -1013,15 +1102,17 @@ for ( i = 0; i < num_params && !face->internal->incremental_interface; i++ ) if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) - face->internal->incremental_interface = params[i].data; + face->internal->incremental_interface = + (FT_Incremental_Interface)params[i].data; } #endif - error = clazz->init_face( stream, - face, - (FT_Int)face_index, - num_params, - params ); + if ( clazz->init_face ) + error = clazz->init_face( stream, + face, + (FT_Int)face_index, + num_params, + params ); if ( error ) goto Fail; @@ -1044,7 +1135,8 @@ if ( error ) { destroy_charmaps( face, memory ); - clazz->done_face( face ); + if ( clazz->done_face ) + clazz->done_face( face ); FT_FREE( internal ); FT_FREE( face ); *aface = 0; @@ -1057,7 +1149,7 @@ /* there's a Mac-specific extended implementation of FT_New_Face() */ /* in src/base/ftmac.c */ -#ifndef FT_MACINTOSH +#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON ) /* documentation is in freetype.h */ @@ -1076,11 +1168,12 @@ args.flags = FT_OPEN_PATHNAME; args.pathname = (char*)pathname; + args.stream = NULL; return FT_Open_Face( library, &args, face_index, aface ); } -#endif /* !FT_MACINTOSH */ +#endif /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */ /* documentation is in freetype.h */ @@ -1102,12 +1195,13 @@ args.flags = FT_OPEN_MEMORY; args.memory_base = file_base; args.memory_size = file_size; + args.stream = NULL; return FT_Open_Face( library, &args, face_index, aface ); } -#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) +#ifdef FT_CONFIG_OPTION_MAC_FONTS /* The behavior here is very similar to that in base/ftmac.c, but it */ /* is designed to work on non-mac systems, so no mac specific calls. */ @@ -1136,9 +1230,9 @@ /* we don't really have access to it. */ - /* Finalizer for a memory stream; gets called by FT_Done_Face(). - It frees the memory it uses. */ - /* from ftmac.c */ + /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ + /* It frees the memory it uses. */ + /* From ftmac.c. */ static void memory_stream_close( FT_Stream stream ) { @@ -1154,7 +1248,7 @@ /* Create a new memory stream from a buffer and a size. */ - /* from ftmac.c */ + /* From ftmac.c. */ static FT_Error new_memory_stream( FT_Library library, FT_Byte* base, @@ -1191,7 +1285,7 @@ /* Create a new FT_Face given a buffer and a driver name. */ /* from ftmac.c */ - static FT_Error + FT_LOCAL_DEF( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, FT_ULong size, @@ -1224,20 +1318,172 @@ args.driver = FT_Get_Module( library, driver_name ); } +#ifdef FT_MACINTOSH + /* At this point, face_index has served its purpose; */ + /* whoever calls this function has already used it to */ + /* locate the correct font data. We should not propagate */ + /* this index to FT_Open_Face() (unless it is negative). */ + + if ( face_index > 0 ) + face_index = 0; +#endif + error = FT_Open_Face( library, &args, face_index, aface ); if ( error == FT_Err_Ok ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; else +#ifdef FT_MACINTOSH + FT_Stream_Free( stream, 0 ); +#else { FT_Stream_Close( stream ); FT_FREE( stream ); } +#endif return error; } + /* Look up `TYP1' or `CID ' table from sfnt table directory. */ + /* `offset' and `length' must exclude the binary header in tables. */ + + /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ + /* format too. Here, since we can't expect that the TrueType font */ + /* driver is loaded unconditially, we must parse the font by */ + /* ourselves. We are only interested in the name of the table and */ + /* the offset. */ + + static FT_Error + ft_lookup_PS_in_sfnt_stream( FT_Stream stream, + FT_Long face_index, + FT_ULong* offset, + FT_ULong* length, + FT_Bool* is_sfnt_cid ) + { + FT_Error error; + FT_UShort numTables; + FT_Long pstable_index; + FT_ULong tag; + int i; + + + *offset = 0; + *length = 0; + *is_sfnt_cid = FALSE; + + /* TODO: support for sfnt-wrapped PS/CID in TTC format */ + + /* version check for 'typ1' (should be ignored?) */ + if ( FT_READ_ULONG( tag ) ) + return error; + if ( tag != TTAG_typ1 ) + return FT_Err_Unknown_File_Format; + + if ( FT_READ_USHORT( numTables ) ) + return error; + if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */ + return error; + + pstable_index = -1; + *is_sfnt_cid = FALSE; + + for ( i = 0; i < numTables; i++ ) + { + if ( FT_READ_ULONG( tag ) || FT_STREAM_SKIP( 4 ) || + FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) ) + return error; + + if ( tag == TTAG_CID ) + { + pstable_index++; + *offset += 22; + *length -= 22; + *is_sfnt_cid = TRUE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + else if ( tag == TTAG_TYP1 ) + { + pstable_index++; + *offset += 24; + *length -= 24; + *is_sfnt_cid = FALSE; + if ( face_index < 0 ) + return FT_Err_Ok; + } + if ( face_index >= 0 && pstable_index == face_index ) + return FT_Err_Ok; + } + return FT_Err_Table_Missing; + } + + + FT_LOCAL_DEF( FT_Error ) + open_face_PS_from_sfnt_stream( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter *params, + FT_Face *aface ) + { + FT_Error error; + FT_Memory memory = library->memory; + FT_ULong offset, length; + FT_Long pos; + FT_Bool is_sfnt_cid; + FT_Byte* sfnt_ps; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + pos = FT_Stream_Pos( stream ); + + error = ft_lookup_PS_in_sfnt_stream( stream, + face_index, + &offset, + &length, + &is_sfnt_cid ); + if ( error ) + goto Exit; + + if ( FT_Stream_Seek( stream, pos + offset ) ) + goto Exit; + + if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); + if ( error ) + goto Exit; + + error = open_face_from_buffer( library, + sfnt_ps, + length, + face_index < 0 ? face_index : 0, + is_sfnt_cid ? "cid" : "type1", + aface ); + Exit: + { + FT_Error error1; + + + if ( error == FT_Err_Unknown_File_Format ) + { + error1 = FT_Stream_Seek( stream, pos ); + if ( error1 ) + return error1; + } + + return error; + } + } + + +#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON ) + /* The resource header says we've got resource_cnt `POST' (type1) */ /* resources in this file. They all need to be coalesced into */ /* one lump which gets passed on to the type1 driver. */ @@ -1392,17 +1638,25 @@ if ( rlen == -1 ) return FT_Err_Cannot_Open_Resource; + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ); + if ( !error ) + goto Exit; + + /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ + if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + goto Exit; + if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) return error; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); if ( error ) goto Exit; - is_cff = rlen > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; - + is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); error = open_face_from_buffer( library, sfnt_data, rlen, @@ -1441,7 +1695,7 @@ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), + TTAG_POST, &data_offsets, &count ); if ( !error ) { @@ -1456,7 +1710,7 @@ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - FT_MAKE_TAG( 's', 'f', 'n', 't' ), + TTAG_sfnt, &data_offsets, &count ); if ( !error ) { @@ -1488,6 +1742,9 @@ FT_Long dlen, offset; + if ( NULL == stream ) + return FT_Err_Invalid_Stream_Operation; + error = FT_Stream_Seek( stream, 0 ); if ( error ) goto Exit; @@ -1544,7 +1801,7 @@ FT_Error errors[FT_RACCESS_N_RULES]; FT_Open_Args args2; - FT_Stream stream2; + FT_Stream stream2 = 0; FT_Raccess_Guess( library, stream, @@ -1599,7 +1856,7 @@ } - /* Check for some macintosh formats. */ + /* Check for some macintosh formats without Carbon framework. */ /* Is this a macbinary file? If so look at the resource fork. */ /* Is this a mac dfont file? */ /* Is this an old style resource fork? (in data) */ @@ -1642,6 +1899,7 @@ face_index, aface, args ); return error; } +#endif #endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ @@ -1657,10 +1915,12 @@ FT_Error error; FT_Driver driver; FT_Memory memory; - FT_Stream stream; + FT_Stream stream = 0; FT_Face face = 0; FT_ListNode node = 0; FT_Bool external_stream; + FT_Module* cur; + FT_Module* limit; /* test for valid `library' delayed to */ @@ -1675,7 +1935,7 @@ /* create input stream */ error = FT_Stream_New( library, args, &stream ); if ( error ) - goto Exit; + goto Fail3; memory = library->memory; @@ -1712,8 +1972,8 @@ else { /* check each font driver for an appropriate format */ - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; + cur = library->modules; + limit = cur + library->num_modules; for ( ; cur < limit; cur++ ) @@ -1738,6 +1998,28 @@ if ( !error ) goto Success; +#ifdef FT_CONFIG_OPTION_MAC_FONTS + if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + FT_ERROR_BASE( error ) == FT_Err_Table_Missing ) + { + /* TrueType but essential tables are missing */ + if ( FT_Stream_Seek( stream, 0 ) ) + break; + + error = open_face_PS_from_sfnt_stream( library, + stream, + face_index, + num_params, + params, + aface ); + if ( !error ) + { + FT_Stream_Free( stream, external_stream ); + return error; + } + } +#endif + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) goto Fail3; } @@ -1747,7 +2029,8 @@ /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */ /* it may be because we have an empty data fork, so we need to check */ /* the resource fork. */ - if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && + if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream && + FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation ) goto Fail2; @@ -2143,12 +2426,24 @@ ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, FT_Pos advance ) { + FT_Pos height = metrics->height; + + + /* compensate for glyph with bbox above/below the baseline */ + if ( metrics->horiBearingY < 0 ) + { + if ( height < metrics->horiBearingY ) + height = metrics->horiBearingY; + } + else if ( metrics->horiBearingY > 0 ) + height -= metrics->horiBearingY; + /* the factor 1.2 is a heuristical value */ if ( !advance ) - advance = metrics->height * 12 / 10; + advance = height * 12 / 10; - metrics->vertBearingX = -( metrics->width / 2 ); - metrics->vertBearingY = ( advance - metrics->height ) / 2; + metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; + metrics->vertBearingY = ( advance - height ) / 2; metrics->vertAdvance = advance; } @@ -2212,8 +2507,8 @@ } else { - metrics->x_scale = 1L << 22; - metrics->y_scale = 1L << 22; + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; metrics->ascender = bsize->y_ppem; metrics->descender = 0; metrics->height = bsize->height << 6; @@ -2324,8 +2619,8 @@ else { FT_ZERO( metrics ); - metrics->x_scale = 1L << 22; - metrics->y_scale = 1L << 22; + metrics->x_scale = 1L << 16; + metrics->y_scale = 1L << 16; } } @@ -2631,6 +2926,8 @@ cur = face->charmaps; if ( !cur ) return FT_Err_Invalid_CharMap_Handle; + if ( FT_Get_CMap_Format( charmap ) == 14 ) + return FT_Err_Invalid_Argument; limit = cur + face->num_charmaps; @@ -2791,7 +3088,12 @@ FT_CMap cmap = FT_CMAP( face->charmap ); - result = cmap->clazz->char_index( cmap, charcode ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); } return result; } @@ -2849,6 +3151,186 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_UInt result = 0; + + + if ( face && face->charmap && + face->charmap->encoding == FT_ENCODING_UNICODE ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + FT_CMap ucmap = FT_CMAP( face->charmap ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_index( vcmap, ucmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ) + { + FT_Int result = -1; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_default( vcmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + result = vcmap->clazz->variant_list( vcmap, memory ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + + result = vcmap->clazz->charvariant_list( vcmap, memory, + (FT_UInt32)charcode ); + } + } + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ) + { + FT_UInt32 *result = NULL; + + + if ( face ) + { + FT_CharMap charmap = find_variant_selector_charmap( face ); + + + if ( charmap != NULL ) + { + FT_CMap vcmap = FT_CMAP( charmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->variantchar_list( vcmap, memory, + (FT_UInt32)variantSelector ); + } + } + + return result; + } + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) @@ -2891,7 +3373,7 @@ ((FT_Byte*)buffer)[0] = 0; if ( face && - glyph_index <= (FT_UInt)face->num_glyphs && + (FT_Long)glyph_index <= face->num_glyphs && FT_HAS_GLYPH_NAMES( face ) ) { FT_Service_GlyphDict service; @@ -2991,6 +3473,7 @@ FT_ULong *length ) { FT_Service_SFNT_Table service; + FT_ULong offset; if ( !face || !FT_IS_SFNT( face ) ) @@ -3000,7 +3483,7 @@ if ( service == NULL ) return FT_Err_Unimplemented_Feature; - return service->table_info( face, table_index, tag, length ); + return service->table_info( face, table_index, tag, &offset, length ); } @@ -3061,11 +3544,11 @@ if ( size == NULL ) - return FT_Err_Bad_Argument; + return FT_Err_Invalid_Argument; face = size->face; if ( face == NULL || face->driver == NULL ) - return FT_Err_Bad_Argument; + return FT_Err_Invalid_Argument; /* we don't need anything more complex than that; all size objects */ /* are already listed by the face */ @@ -3325,7 +3808,7 @@ while ( renderer ) { error = renderer->render( renderer, slot, render_mode, NULL ); - if ( !error || + if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) break; @@ -3723,11 +4206,23 @@ library->memory = memory; +#ifdef FT_CONFIG_OPTION_PIC + /* initialize position independent code containers */ + error = ft_pic_container_init( library ); + if ( error ) + goto Fail; +#endif + /* allocate the render pool */ library->raster_pool_size = FT_RENDER_POOL_SIZE; - if ( FT_RENDER_POOL_SIZE > 0 ) - if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; +#if FT_RENDER_POOL_SIZE > 0 + if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; +#endif + + library->version_major = FREETYPE_MAJOR; + library->version_minor = FREETYPE_MINOR; + library->version_patch = FREETYPE_PATCH; /* That's ok now */ *alibrary = library; @@ -3735,6 +4230,9 @@ return FT_Err_Ok; Fail: +#ifdef FT_CONFIG_OPTION_PIC + ft_pic_container_destroy( library ); +#endif FT_FREE( library ); return error; } @@ -3812,7 +4310,11 @@ faces = &FT_DRIVER(module)->faces_list; while ( faces->head ) + { FT_Done_Face( FT_FACE( faces->head->data ) ); + if ( faces->head ) + FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" )); + } } } @@ -3847,6 +4349,11 @@ FT_FREE( library->raster_pool ); library->raster_pool_size = 0; +#ifdef FT_CONFIG_OPTION_PIC + /* Destroy pic container contents */ + ft_pic_container_destroy( library ); +#endif + FT_FREE( library ); return FT_Err_Ok; } diff --git a/lib/3rdparty/freetype/src/base/ftotval.c b/lib/3rdparty/freetype/src/base/ftotval.c index b6de6db85d1..20ed686eee6 100644 --- a/lib/3rdparty/freetype/src/base/ftotval.c +++ b/lib/3rdparty/freetype/src/base/ftotval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (body). */ /* */ -/* Copyright 2004, 2006 by */ +/* Copyright 2004, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,6 +18,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_OPENTYPE_VALIDATE_H +#include FT_OPENTYPE_VALIDATE_H /* documentation is in ftotval.h */ diff --git a/lib/3rdparty/freetype/src/base/ftoutln.c b/lib/3rdparty/freetype/src/base/ftoutln.c index 6926f3a09a7..b69df84c04c 100644 --- a/lib/3rdparty/freetype/src/base/ftoutln.c +++ b/lib/3rdparty/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include <ft2build.h> #include FT_OUTLINE_H #include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H #include FT_TRIGONOMETRY_H @@ -83,21 +84,25 @@ FT_Int last; /* index of last point in contour */ + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + last = outline->contours[n]; if ( last < 0 ) goto Invalid_Outline; limit = outline->points + last; - v_start = outline->points[first]; - v_last = outline->points[last]; + v_start = outline->points[first]; + v_start.x = SCALED( v_start.x ); + v_start.y = SCALED( v_start.y ); - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); v_control = v_start; point = outline->points + first; - tags = outline->tags + first; + tags = outline->tags + first; tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ @@ -128,6 +133,8 @@ tags--; } + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->move_to( &v_start, user ); if ( error ) goto Exit; @@ -148,6 +155,8 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); error = func_interface->line_to( &vec, user ); if ( error ) goto Exit; @@ -174,6 +183,10 @@ if ( tag == FT_CURVE_TAG_ON ) { + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); error = func_interface->conic_to( &v_control, &vec, user ); if ( error ) goto Exit; @@ -186,6 +199,10 @@ v_middle.x = ( v_control.x + vec.x ) / 2; v_middle.y = ( v_control.y + vec.y ) / 2; + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); error = func_interface->conic_to( &v_control, &v_middle, user ); if ( error ) goto Exit; @@ -194,6 +211,10 @@ goto Do_Conic; } + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); error = func_interface->conic_to( &v_control, &v_start, user ); goto Close; @@ -209,8 +230,11 @@ point += 2; tags += 2; - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); + vec1.x = SCALED( point[-2].x ); + vec1.y = SCALED( point[-2].y ); + + vec2.x = SCALED( point[-1].x ); + vec2.y = SCALED( point[-1].y ); if ( point <= limit ) { @@ -220,12 +244,22 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); if ( error ) goto Exit; continue; } + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); goto Close; } @@ -233,6 +267,8 @@ } /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->line_to( &v_start, user ); Close: @@ -242,9 +278,11 @@ first = last + 1; } - return 0; + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); + return FT_Err_Ok; Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); return error; Invalid_Outline: @@ -266,9 +304,9 @@ *anoutline = null_outline; - if ( FT_NEW_ARRAY( anoutline->points, numPoints * 2L ) || - FT_NEW_ARRAY( anoutline->tags, numPoints ) || - FT_NEW_ARRAY( anoutline->contours, numContours ) ) + if ( FT_NEW_ARRAY( anoutline->points, numPoints ) || + FT_NEW_ARRAY( anoutline->tags, numPoints ) || + FT_NEW_ARRAY( anoutline->contours, numContours ) ) goto Fail; anoutline->n_points = (FT_UShort)numPoints; @@ -474,12 +512,14 @@ FT_Pos yOffset ) { FT_UShort n; - FT_Vector* vec = outline->points; + FT_Vector* vec; if ( !outline ) return; + vec = outline->points; + for ( n = 0; n < outline->n_points; n++ ) { vec->x += xOffset; @@ -556,7 +596,7 @@ FT_Raster_Params* params ) { FT_Error error; - FT_Bool update = 0; + FT_Bool update = FALSE; FT_Renderer renderer; FT_ListNode node; @@ -587,7 +627,7 @@ /* format */ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, &node ); - update = 1; + update = TRUE; } /* if we changed the current renderer for the glyph image format */ @@ -626,13 +666,13 @@ } - /* documentation is in ftoutln.h */ + /* documentation is in freetype.h */ FT_EXPORT_DEF( void ) FT_Vector_Transform( FT_Vector* vector, const FT_Matrix* matrix ) { - FT_Pos xz, yz; + FT_Pos xz, yz; if ( !vector || !matrix ) @@ -1005,7 +1045,7 @@ } } - if ( xmin == 32768 ) + if ( xmin == 32768L ) return FT_ORIENTATION_TRUETYPE; ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; diff --git a/lib/3rdparty/freetype/src/base/ftpatent.c b/lib/3rdparty/freetype/src/base/ftpatent.c index d63f191c3ea..501cab52cad 100644 --- a/lib/3rdparty/freetype/src/base/ftpatent.c +++ b/lib/3rdparty/freetype/src/base/ftpatent.c @@ -5,7 +5,7 @@ /* FreeType API for checking patented TrueType bytecode instructions */ /* (body). */ /* */ -/* Copyright 2007 by David Turner. */ +/* Copyright 2007, 2008, 2010 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -103,6 +103,7 @@ } Exit: + FT_UNUSED( error ); FT_FRAME_EXIT(); return result; } @@ -113,7 +114,7 @@ FT_ULong tag ) { FT_Stream stream = face->stream; - FT_Error error; + FT_Error error = FT_Err_Ok; FT_Service_SFNT_Table service; FT_Bool result = FALSE; @@ -122,15 +123,19 @@ if ( service ) { - FT_ULong offset, size; + FT_UInt i = 0; + FT_ULong tag_i = 0, offset_i = 0, length_i = 0; - error = service->table_info( face, tag, &offset, &size ); - if ( error || - FT_STREAM_SEEK( offset ) ) + for ( i = 0; !error && tag_i != tag ; i++ ) + error = service->table_info( face, i, + &tag_i, &offset_i, &length_i ); + + if ( error || + FT_STREAM_SEEK( offset_i ) ) goto Exit; - result = _tt_check_patents_in_range( stream, size ); + result = _tt_check_patents_in_range( stream, length_i ); } Exit: @@ -260,7 +265,7 @@ FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ) { - FT_Bool result = 0; + FT_Bool result = FALSE; #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ diff --git a/lib/3rdparty/freetype/src/base/ftpfr.c b/lib/3rdparty/freetype/src/base/ftpfr.c index 9e930ddf7e3..f9592bb1bba 100644 --- a/lib/3rdparty/freetype/src/base/ftpfr.c +++ b/lib/3rdparty/freetype/src/base/ftpfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002, 2003, 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,6 +46,9 @@ FT_Service_PfrMetrics service; + if ( !face ) + return FT_Err_Invalid_Argument; + service = ft_pfr_check( face ); if ( service ) { @@ -55,14 +58,17 @@ ametrics_x_scale, ametrics_y_scale ); } - else if ( face ) + else { FT_Fixed x_scale, y_scale; /* this is not a PFR font */ - *aoutline_resolution = face->units_per_EM; - *ametrics_resolution = face->units_per_EM; + if ( aoutline_resolution ) + *aoutline_resolution = face->units_per_EM; + + if ( ametrics_resolution ) + *ametrics_resolution = face->units_per_EM; x_scale = y_scale = 0x10000L; if ( face->size ) @@ -70,11 +76,15 @@ x_scale = face->size->metrics.x_scale; y_scale = face->size->metrics.y_scale; } - *ametrics_x_scale = x_scale; - *ametrics_y_scale = y_scale; + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + error = FT_Err_Unknown_File_Format; } - else - error = FT_Err_Invalid_Argument; return error; } @@ -92,14 +102,15 @@ FT_Service_PfrMetrics service; + if ( !face ) + return FT_Err_Invalid_Argument; + service = ft_pfr_check( face ); if ( service ) error = service->get_kerning( face, left, right, avector ); - else if ( face ) + else error = FT_Get_Kerning( face, left, right, FT_KERNING_UNSCALED, avector ); - else - error = FT_Err_Invalid_Argument; return error; } diff --git a/lib/3rdparty/freetype/src/base/ftpic.c b/lib/3rdparty/freetype/src/base/ftpic.c new file mode 100644 index 00000000000..d5271a9726a --- /dev/null +++ b/lib/3rdparty/freetype/src/base/ftpic.c @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* ftpic.c */ +/* */ +/* The FreeType position independent code services (body). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "basepic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* documentation is in ftpic.h */ + + FT_BASE_DEF( FT_Error ) + ft_pic_container_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + + FT_MEM_SET( pic_container, 0, sizeof(*pic_container) ); + + error = ft_base_pic_init( library ); + if(error) + return error; + + return FT_Err_Ok; + } + + + /* Destroy the contents of the container. */ + FT_BASE_DEF( void ) + ft_pic_container_destroy( FT_Library library ) + { + ft_base_pic_free( library ); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftrfork.c b/lib/3rdparty/freetype/src/base/ftrfork.c index a4f726d9303..133c2de0575 100644 --- a/lib/3rdparty/freetype/src/base/ftrfork.c +++ b/lib/3rdparty/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -132,6 +132,19 @@ } + static int + ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, + FT_RFork_Ref* b ) + { + if ( a->res_id < b->res_id ) + return -1; + else if ( a->res_id > b->res_id ) + return 1; + else + return 0; + } + + FT_BASE_DEF( FT_Error ) FT_Raccess_Get_DataOffsets( FT_Library library, FT_Stream stream, @@ -141,12 +154,13 @@ FT_Long **offsets, FT_Long *count ) { - FT_Error error; - int i, j, cnt, subcnt; - FT_Long tag_internal, rpos; - FT_Memory memory = library->memory; - FT_Long temp; - FT_Long *offsets_internal; + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal; + FT_RFork_Ref *ref; error = FT_Stream_Seek( stream, map_offset ); @@ -179,28 +193,43 @@ if ( error ) return error; - if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + if ( FT_NEW_ARRAY( ref, *count ) ) return error; for ( j = 0; j < *count; ++j ) { - (void)FT_STREAM_SKIP( 2 ); /* resource id */ - (void)FT_STREAM_SKIP( 2 ); /* rsource name */ - + if ( FT_READ_USHORT( ref[j].res_id ) ) + goto Exit; + if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + goto Exit; if ( FT_READ_LONG( temp ) ) - { - FT_FREE( offsets_internal ); - return error; - } + goto Exit; + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + goto Exit; - offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL ); - - (void)FT_STREAM_SKIP( 4 ); /* mbz */ + ref[j].offset = temp & 0xFFFFFFL; } - *offsets = offsets_internal; + ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); - return FT_Err_Ok; + if ( FT_NEW_ARRAY( offsets_internal, *count ) ) + goto Exit; + + /* XXX: duplicated reference ID, + * gap between reference IDs are acceptable? + * further investigation on Apple implementation is needed. + */ + for ( j = 0; j < *count; ++j ) + offsets_internal[j] = rdata_pos + ref[j].offset; + + *offsets = offsets_internal; + error = FT_Err_Ok; + + Exit: + FT_FREE( ref ); + return error; } } @@ -227,7 +256,7 @@ typedef FT_Error (*raccess_guess_func)( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); @@ -235,56 +264,63 @@ static FT_Error raccess_guess_apple_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_apple_single( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_darwin_ufs_export( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ); + static FT_Error raccess_guess_darwin_hfsplus( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_vfat( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_cap( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); static FT_Error raccess_guess_linux_netatalk( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ); @@ -298,7 +334,7 @@ static FT_Error raccess_guess_apple_generic( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, FT_Int32 magic, FT_Long *result_offset ); @@ -329,6 +365,7 @@ raccess_guess_apple_double, raccess_guess_apple_single, raccess_guess_darwin_ufs_export, + raccess_guess_darwin_newvfs, raccess_guess_darwin_hfsplus, raccess_guess_vfat, raccess_guess_linux_cap, @@ -339,7 +376,11 @@ for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) { new_names[i] = NULL; - errors[i] = FT_Stream_Seek( stream, 0 ); + if ( NULL != stream ) + errors[i] = FT_Stream_Seek( stream, 0 ); + else + errors[i] = FT_Err_Ok; + if ( errors[i] ) continue ; @@ -354,14 +395,20 @@ static FT_Error raccess_guess_apple_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { - FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 ); + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x07; *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + return raccess_guess_apple_generic( library, stream, base_file_name, magic, result_offset ); } @@ -370,14 +417,20 @@ static FT_Error raccess_guess_apple_single( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { - FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00); + FT_Int32 magic = ( 0x00 << 24 ) | + ( 0x05 << 16 ) | + ( 0x16 << 8 ) | + 0x00; *result_file_name = NULL; + if ( NULL == stream ) + return FT_Err_Cannot_Open_Stream; + return raccess_guess_apple_generic( library, stream, base_file_name, magic, result_offset ); } @@ -386,7 +439,7 @@ static FT_Error raccess_guess_darwin_ufs_export( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -416,7 +469,7 @@ static FT_Error raccess_guess_darwin_hfsplus( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -433,7 +486,7 @@ memory = library->memory; - if ( base_file_len > FT_INT_MAX ) + if ( base_file_len + 6 > FT_INT_MAX ) return FT_Err_Array_Too_Large; if ( FT_ALLOC( newpath, base_file_len + 6 ) ) @@ -449,10 +502,46 @@ } + static FT_Error + raccess_guess_darwin_newvfs( FT_Library library, + FT_Stream stream, + char *base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with Mac OS X (> 10.1). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + FT_Long base_file_len = ft_strlen( base_file_name ); + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( base_file_len + 18 > FT_INT_MAX ) + return FT_Err_Array_Too_Large; + + if ( FT_ALLOC( newpath, base_file_len + 18 ) ) + return error; + + FT_MEM_COPY( newpath, base_file_name, base_file_len ); + FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + static FT_Error raccess_guess_vfat( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -479,7 +568,7 @@ static FT_Error raccess_guess_linux_cap( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -505,7 +594,7 @@ static FT_Error raccess_guess_linux_double( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -536,7 +625,7 @@ static FT_Error raccess_guess_linux_netatalk( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, char **result_file_name, FT_Long *result_offset ) { @@ -568,7 +657,7 @@ static FT_Error raccess_guess_apple_generic( FT_Library library, FT_Stream stream, - char * base_file_name, + char *base_file_name, FT_Int32 magic, FT_Long *result_offset ) { @@ -620,8 +709,12 @@ return FT_Err_Ok; } else - FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + { + error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + if ( error ) + return error; } + } return FT_Err_Unknown_File_Format; } @@ -629,7 +722,7 @@ static FT_Error raccess_guess_linux_double_from_file_name( FT_Library library, - char * file_name, + char *file_name, FT_Long *result_offset ) { FT_Open_Args args2; @@ -659,9 +752,9 @@ const char *insertion ) { char* new_name; - char* tmp; + const char* tmp; const char* slash; - unsigned new_length; + size_t new_length; FT_Error error = FT_Err_Ok; FT_UNUSED( error ); @@ -701,7 +794,7 @@ FT_BASE_DEF( void ) FT_Raccess_Guess( FT_Library library, FT_Stream stream, - char* base_name, + char *base_name, char **new_names, FT_Long *offsets, FT_Error *errors ) diff --git a/lib/3rdparty/freetype/src/base/ftsnames.c b/lib/3rdparty/freetype/src/base/ftsnames.c new file mode 100644 index 00000000000..3447888ca23 --- /dev/null +++ b/lib/3rdparty/freetype/src/base/ftsnames.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftsnames.c */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (body). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_SFNT_NAMES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_STREAM_H + + +#ifdef TT_CONFIG_OPTION_SFNT_NAMES + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0; + } + + + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( aname && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( idx < (FT_UInt)ttface->num_names ) + { + TT_NameEntryRec* entry = ttface->name_table.names + idx; + + + /* load name on demand */ + if ( entry->stringLength > 0 && entry->string == NULL ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + aname->platform_id = entry->platformID; + aname->encoding_id = entry->encodingID; + aname->language_id = entry->languageID; + aname->name_id = entry->nameID; + aname->string = (FT_Byte*)entry->string; + aname->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + +#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/ftstream.c b/lib/3rdparty/freetype/src/base/ftstream.c index a067a1fde7d..b638599dbcf 100644 --- a/lib/3rdparty/freetype/src/base/ftstream.c +++ b/lib/3rdparty/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2001, 2002, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,13 +60,12 @@ FT_Error error = FT_Err_Ok; - stream->pos = pos; - if ( stream->read ) { if ( stream->read( stream, pos, 0, 0 ) ) { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; @@ -75,12 +74,16 @@ /* note that seeking to the first position after the file is valid */ else if ( pos > stream->size ) { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_Seek:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; } + if ( !error ) + stream->pos = pos; + return error; } @@ -89,6 +92,9 @@ FT_Stream_Skip( FT_Stream stream, FT_Long distance ) { + if ( distance < 0 ) + return FT_Err_Invalid_Stream_Operation; + return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); } @@ -121,7 +127,8 @@ if ( pos >= stream->size ) { - FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); return FT_Err_Invalid_Stream_Operation; @@ -142,8 +149,8 @@ if ( read_bytes < count ) { - FT_ERROR(( "FT_Stream_ReadAt:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + FT_ERROR(( "FT_Stream_ReadAt:" + " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); error = FT_Err_Invalid_Stream_Operation; @@ -208,7 +215,7 @@ FT_Stream_ReleaseFrame( FT_Stream stream, FT_Byte** pbytes ) { - if ( stream->read ) + if ( stream && stream->read ) { FT_Memory memory = stream->memory; @@ -253,8 +260,8 @@ stream->base, count ); if ( read_bytes < count ) { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); FT_FREE( stream->base ); @@ -270,8 +277,8 @@ if ( stream->pos >= stream->size || stream->pos + count > stream->size ) { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_EnterFrame:" + " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", stream->pos, count, stream->size )); error = FT_Err_Invalid_Stream_Operation; @@ -456,7 +463,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadChar:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -502,8 +510,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShort:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadShort:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -549,8 +557,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShortLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadShortLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -596,8 +604,8 @@ Fail: *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadOffset:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + FT_ERROR(( "FT_Stream_ReadOffset:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); return 0; @@ -642,9 +650,10 @@ return result; Fail: - FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLong:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); return 0; } @@ -688,10 +697,10 @@ return result; Fail: - FT_ERROR(( "FT_Stream_ReadLongLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadLongLE:" + " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); return 0; } @@ -704,12 +713,13 @@ { FT_Error error; FT_Bool frame_accessed = 0; - FT_Byte* cursor = stream->cursor; - + FT_Byte* cursor; if ( !fields || !stream ) return FT_Err_Invalid_Argument; + cursor = stream->cursor; + error = FT_Err_Ok; do { diff --git a/lib/3rdparty/freetype/src/base/ftstroke.c b/lib/3rdparty/freetype/src/base/ftstroke.c index 8f7e0459da4..75bcbded6a3 100644 --- a/lib/3rdparty/freetype/src/base/ftstroke.c +++ b/lib/3rdparty/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -230,7 +230,7 @@ /***************************************************************************/ /***************************************************************************/ - typedef enum + typedef enum FT_StrokeTags_ { FT_STROKE_TAG_ON = 1, /* on-curve point */ FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ @@ -261,7 +261,7 @@ { FT_UInt old_max = border->max_points; FT_UInt new_max = border->num_points + new_points; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; if ( new_max > old_max ) @@ -279,6 +279,7 @@ border->max_points = cur_max; } + Exit: return error; } @@ -346,7 +347,7 @@ } border->start = -1; - border->movable = 0; + border->movable = FALSE; } @@ -355,7 +356,7 @@ FT_Vector* to, FT_Bool movable ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_ASSERT( border->start >= 0 ); @@ -410,7 +411,7 @@ border->num_points += 2; } - border->movable = 0; + border->movable = FALSE; return error; } @@ -443,7 +444,7 @@ border->num_points += 3; } - border->movable = 0; + border->movable = FALSE; return error; } @@ -461,7 +462,7 @@ FT_Angle total, angle, step, rotate, next, theta; FT_Vector a, b, a2, b2; FT_Fixed length; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; /* compute start point */ @@ -527,12 +528,12 @@ { /* close current open path if any ? */ if ( border->start >= 0 ) - ft_stroke_border_close( border, 0 ); + ft_stroke_border_close( border, FALSE ); border->start = border->num_points; - border->movable = 0; + border->movable = FALSE; - return ft_stroke_border_lineto( border, to, 0 ); + return ft_stroke_border_lineto( border, to, FALSE ); } @@ -547,7 +548,7 @@ border->num_points = 0; border->max_points = 0; border->start = -1; - border->valid = 0; + border->valid = FALSE; } @@ -556,7 +557,7 @@ { border->num_points = 0; border->start = -1; - border->valid = 0; + border->valid = FALSE; } @@ -572,7 +573,7 @@ border->num_points = 0; border->max_points = 0; border->start = -1; - border->valid = 0; + border->valid = FALSE; } @@ -581,7 +582,7 @@ FT_UInt *anum_points, FT_UInt *anum_contours ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_UInt num_points = 0; FT_UInt num_contours = 0; @@ -605,9 +606,6 @@ if ( tags[0] & FT_STROKE_TAG_END ) { - if ( in_contour == 0 ) - goto Fail; - in_contour = 0; num_contours++; } @@ -616,7 +614,7 @@ if ( in_contour != 0 ) goto Fail; - border->valid = 1; + border->valid = TRUE; Exit: *anum_points = num_points; @@ -708,7 +706,7 @@ FT_Bool valid; FT_StrokeBorderRec borders[2]; - FT_Memory memory; + FT_Library library; } FT_StrokerRec; @@ -731,7 +729,7 @@ if ( !FT_NEW( stroker ) ) { - stroker->memory = memory; + stroker->library = library; ft_stroke_border_init( &stroker->borders[0], memory ); ft_stroke_border_init( &stroker->borders[1], memory ); @@ -779,13 +777,13 @@ { if ( stroker ) { - FT_Memory memory = stroker->memory; + FT_Memory memory = stroker->library->memory; ft_stroke_border_done( &stroker->borders[0] ); ft_stroke_border_done( &stroker->borders[1] ); - stroker->memory = NULL; + stroker->library = NULL; FT_FREE( stroker ); } } @@ -798,7 +796,7 @@ { FT_Angle total, rotate; FT_Fixed radius = stroker->radius; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_StrokeBorder border = stroker->borders + side; @@ -813,7 +811,7 @@ radius, stroker->angle_in + rotate, total ); - border->movable = 0; + border->movable = FALSE; return error; } @@ -824,7 +822,7 @@ FT_Angle angle, FT_Int side ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) @@ -849,7 +847,7 @@ delta.x += stroker->center.x + delta2.x; delta.y += stroker->center.y + delta2.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); if ( error ) goto Exit; @@ -859,7 +857,32 @@ delta.x += delta2.x + stroker->center.x; delta.y += delta2.y + stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT ) + { + /* add a butt ending */ + FT_Vector delta; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + + FT_Vector_From_Polar( &delta, radius, angle + rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; + + FT_Vector_From_Polar( &delta, radius, angle - rotate ); + + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, FALSE ); } Exit: @@ -876,7 +899,7 @@ FT_Angle phi, theta, rotate; FT_Fixed length, thcos, sigma; FT_Vector delta; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; rotate = FT_SIDE_TO_ROTATE( side ); @@ -900,7 +923,7 @@ stroker->angle_out + rotate ); delta.x += stroker->center.x; delta.y += stroker->center.y; - border->movable = 0; + border->movable = FALSE; } else { @@ -911,7 +934,7 @@ delta.y += stroker->center.y; } - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); return error; } @@ -928,9 +951,7 @@ if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) - { error = ft_stroker_arcto( stroker, side ); - } else { /* this is a mitered or beveled corner */ @@ -943,7 +964,7 @@ rotate = FT_SIDE_TO_ROTATE( side ); miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); - theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); if ( theta == FT_ANGLE_PI ) { theta = rotate; @@ -958,8 +979,9 @@ thcos = FT_Cos( theta ); sigma = FT_MulFix( stroker->miter_limit, thcos ); - if ( sigma >= 0x10000L ) - miter = 0; + /* FT_Sin(x) = 0 for x <= 57 */ + if ( sigma >= 0x10000L || ft_pos_abs( theta ) <= 57 ) + miter = FALSE; if ( miter ) /* this is a miter (broken angle) */ { @@ -983,7 +1005,7 @@ delta.x += middle.x; delta.y += middle.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); if ( error ) goto Exit; @@ -992,7 +1014,7 @@ delta.x += middle.x; delta.y += middle.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); + error = ft_stroke_border_lineto( border, &delta, FALSE ); if ( error ) goto Exit; @@ -1001,7 +1023,7 @@ delta.x += stroker->center.x; delta.y += stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 1 ); + error = ft_stroke_border_lineto( border, &delta, TRUE ); } else /* this is a bevel (intersection) */ @@ -1016,8 +1038,9 @@ delta.x += stroker->center.x; delta.y += stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + error = ft_stroke_border_lineto( border, &delta, FALSE ); + if ( error ) + goto Exit; /* now add end point */ FT_Vector_From_Polar( &delta, stroker->radius, @@ -1025,7 +1048,7 @@ delta.x += stroker->center.x; delta.y += stroker->center.y; - error = ft_stroke_border_lineto( border, &delta, 1 ); + error = ft_stroke_border_lineto( border, &delta, TRUE ); } } @@ -1037,7 +1060,7 @@ static FT_Error ft_stroker_process_corner( FT_Stroker stroker ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_Angle turn; FT_Int inside_side; @@ -1069,7 +1092,7 @@ /* add two points to the left and right borders corresponding to the */ - /* start of the subpath.. */ + /* start of the subpath */ static FT_Error ft_stroker_subpath_start( FT_Stroker stroker, FT_Angle start_angle ) @@ -1099,7 +1122,7 @@ /* save angle for last cap */ stroker->subpath_angle = start_angle; - stroker->first_point = 0; + stroker->first_point = FALSE; Exit: return error; @@ -1112,7 +1135,7 @@ FT_Stroker_LineTo( FT_Stroker stroker, FT_Vector* to ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_StrokeBorder border; FT_Vector delta; FT_Angle angle; @@ -1143,7 +1166,7 @@ goto Exit; } - /* now add a line segment to both the "inside" and "outside" paths */ + /* now add a line segment to both the `inside' and `outside' paths */ for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) { @@ -1153,7 +1176,7 @@ point.x = to->x + delta.x; point.y = to->y + delta.y; - error = ft_stroke_border_lineto( border, &point, 1 ); + error = ft_stroke_border_lineto( border, &point, TRUE ); if ( error ) goto Exit; @@ -1176,12 +1199,12 @@ FT_Vector* control, FT_Vector* to ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_Vector bez_stack[34]; FT_Vector* arc; FT_Vector* limit = bez_stack + 30; FT_Angle start_angle; - FT_Bool first_arc = 1; + FT_Bool first_arc = TRUE; arc = bez_stack; @@ -1206,7 +1229,7 @@ if ( first_arc ) { - first_arc = 0; + first_arc = FALSE; start_angle = angle_in; @@ -1275,12 +1298,12 @@ FT_Vector* control2, FT_Vector* to ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_Vector bez_stack[37]; FT_Vector* arc; FT_Vector* limit = bez_stack + 32; FT_Angle start_angle; - FT_Bool first_arc = 1; + FT_Bool first_arc = TRUE; arc = bez_stack; @@ -1308,7 +1331,7 @@ if ( first_arc ) { - first_arc = 0; + first_arc = FALSE; /* process corner if necessary */ start_angle = angle_in; @@ -1338,7 +1361,7 @@ phi1 = (angle_mid + angle_in ) / 2; phi2 = (angle_mid + angle_out ) / 2; length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); - length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); + length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) ); for ( side = 0; side <= 1; side++ ) { @@ -1386,15 +1409,16 @@ { /* We cannot process the first point, because there is not enough */ /* information regarding its corner/cap. The latter will be processed */ - /* in the "end_subpath" routine. */ + /* in the `FT_Stroker_EndSubPath' routine. */ /* */ - stroker->first_point = 1; - stroker->center = *to; - stroker->subpath_open = open; + stroker->first_point = TRUE; + stroker->center = *to; + stroker->subpath_open = open; - /* record the subpath start point index for each border */ + /* record the subpath start point for each border */ stroker->subpath_start = *to; - return 0; + + return FT_Err_Ok; } @@ -1402,10 +1426,10 @@ ft_stroker_add_reverse_left( FT_Stroker stroker, FT_Bool open ) { - FT_StrokeBorder right = stroker->borders + 0; - FT_StrokeBorder left = stroker->borders + 1; + FT_StrokeBorder right = stroker->borders + 0; + FT_StrokeBorder left = stroker->borders + 1; FT_Int new_points; - FT_Error error = 0; + FT_Error error = FT_Err_Ok; FT_ASSERT( left->start >= 0 ); @@ -1452,8 +1476,8 @@ left->num_points = left->start; right->num_points += new_points; - right->movable = 0; - left->movable = 0; + right->movable = FALSE; + left->movable = FALSE; } Exit: @@ -1467,7 +1491,8 @@ FT_EXPORT_DEF( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ) { - FT_Error error = 0; + FT_Error error = FT_Err_Ok; + if ( stroker->subpath_open ) { @@ -1480,8 +1505,8 @@ if ( error ) goto Exit; - /* add reversed points from "left" to "right" */ - error = ft_stroker_add_reverse_left( stroker, 1 ); + /* add reversed points from `left' to `right' */ + error = ft_stroker_add_reverse_left( stroker, TRUE ); if ( error ) goto Exit; @@ -1494,7 +1519,7 @@ /* Now end the right subpath accordingly. The left one is */ /* rewind and doesn't need further processing. */ - ft_stroke_border_close( right, 0 ); + ft_stroke_border_close( right, FALSE ); } else { @@ -1536,8 +1561,8 @@ } /* then end our two subpaths */ - ft_stroke_border_close( stroker->borders + 0, 1 ); - ft_stroke_border_close( stroker->borders + 1, 0 ); + ft_stroke_border_close( stroker->borders + 0, TRUE ); + ft_stroke_border_close( stroker->borders + 1, FALSE ); } Exit: @@ -1692,7 +1717,7 @@ v_control = v_start; point = outline->points + first; - tags = outline->tags + first; + tags = outline->tags + first; tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ @@ -1711,13 +1736,10 @@ } else { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ + /* if both first and last points are conic, */ + /* start at their middle */ v_start.x = ( v_start.x + v_last.x ) / 2; v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; } point--; tags--; @@ -1836,7 +1858,7 @@ first = last + 1; } - return 0; + return FT_Err_Ok; Exit: return error; @@ -1845,8 +1867,13 @@ return FT_Err_Invalid_Outline; } - +/* declare an extern to access ft_outline_glyph_class global allocated + in ftglyph.c, and use the FT_OUTLINE_GLYPH_CLASS_GET macro to access + it when FT_CONFIG_OPTION_PIC is defined */ +#ifndef FT_CONFIG_OPTION_PIC extern const FT_Glyph_Class ft_outline_glyph_class; +#endif +#include "basepic.h" /* documentation is in ftstroke.h */ @@ -1858,13 +1885,14 @@ { FT_Error error = FT_Err_Invalid_Argument; FT_Glyph glyph = NULL; - + FT_Library library = stroker->library; + FT_UNUSED(library); if ( pglyph == NULL ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -1884,7 +1912,7 @@ FT_UInt num_points, num_contours; - error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); if ( error ) goto Fail; @@ -1931,13 +1959,14 @@ { FT_Error error = FT_Err_Invalid_Argument; FT_Glyph glyph = NULL; - + FT_Library library = stroker->library; + FT_UNUSED(library); if ( pglyph == NULL ) goto Exit; glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET ) goto Exit; { @@ -1967,7 +1996,7 @@ border = FT_STROKER_BORDER_LEFT; } - error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + error = FT_Stroker_ParseOutline( stroker, outline, FALSE ); if ( error ) goto Fail; diff --git a/lib/3rdparty/freetype/src/base/ftsynth.c b/lib/3rdparty/freetype/src/base/ftsynth.c index ff88ce96c5b..ba3c633e28e 100644 --- a/lib/3rdparty/freetype/src/base/ftsynth.c +++ b/lib/3rdparty/freetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,11 +18,21 @@ #include <ft2build.h> #include FT_SYNTHESIS_H +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H #include FT_BITMAP_H + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_synth + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -68,36 +78,13 @@ /*************************************************************************/ - FT_EXPORT_DEF( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) - { - if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && - !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) - { - FT_Bitmap bitmap; - FT_Error error; - - - FT_Bitmap_New( &bitmap ); - error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); - if ( error ) - return error; - - slot->bitmap = bitmap; - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - } - - return FT_Err_Ok; - } - - /* documentation is in ftsynth.h */ FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { FT_Library library = slot->library; - FT_Face face = FT_SLOT_FACE( slot ); + FT_Face face = slot->face; FT_Error error; FT_Pos xstr, ystr; @@ -113,8 +100,8 @@ if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) { - error = FT_Outline_Embolden( &slot->outline, xstr ); /* ignore error */ + (void)FT_Outline_Embolden( &slot->outline, xstr ); /* this is more than enough for most glyphs; if you need accurate */ /* values, you have to call FT_Outline_Get_CBox */ @@ -123,11 +110,24 @@ } else if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) { - xstr = FT_PIX_FLOOR( xstr ); + /* round to full pixels */ + xstr &= ~63; if ( xstr == 0 ) xstr = 1 << 6; - ystr = FT_PIX_FLOOR( ystr ); + ystr &= ~63; + /* + * XXX: overflow check for 16-bit system, for compatibility + * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * unfortunately, this function return no informations + * about the cause of error. + */ + if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) + { + FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); + FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); + return; + } error = FT_GlyphSlot_Own_Bitmap( slot ); if ( error ) return; @@ -151,8 +151,9 @@ slot->metrics.vertBearingY += ystr; slot->metrics.vertAdvance += ystr; + /* XXX: 16-bit overflow case must be excluded before here */ if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - slot->bitmap_top += ystr >> 6; + slot->bitmap_top += (FT_Int)( ystr >> 6 ); } diff --git a/lib/3rdparty/freetype/src/base/ftsystem.c b/lib/3rdparty/freetype/src/base/ftsystem.c index f61a3edfb6b..4d06d6db5cc 100644 --- a/lib/3rdparty/freetype/src/base/ftsystem.c +++ b/lib/3rdparty/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2006 by */ +/* Copyright 1996-2001, 2002, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -205,7 +205,8 @@ file = STREAM_FILE( stream ); - ft_fseek( file, offset, SEEK_SET ); + if ( stream->pos != offset ) + ft_fseek( file, offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); } @@ -226,8 +227,8 @@ file = ft_fopen( filepathname, "rb" ); if ( !file ) { - FT_ERROR(( "FT_Stream_Open:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); + FT_ERROR(( "FT_Stream_Open:" + " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } @@ -294,7 +295,7 @@ #ifdef FT_DEBUG_MEMORY ft_mem_debug_done( memory ); #endif - memory->free( memory, memory ); + ft_sfree( memory ); } diff --git a/lib/3rdparty/freetype/src/base/fttrigon.c b/lib/3rdparty/freetype/src/base/fttrigon.c index 9f513946b83..fdf433ab866 100644 --- a/lib/3rdparty/freetype/src/base/fttrigon.c +++ b/lib/3rdparty/freetype/src/base/fttrigon.c @@ -72,10 +72,10 @@ val = ( val >= 0 ) ? val : -val; v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)val & 0xFFFFL; + v2 = (FT_UInt32)(val & 0xFFFFL); - k1 = FT_TRIG_SCALE >> 16; /* constant */ - k2 = FT_TRIG_SCALE & 0xFFFFL; /* constant */ + k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ + k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL); /* constant */ hi = k1 * v1; lo1 = k1 * v2 + k2 * v1; /* can't overflow */ @@ -86,7 +86,7 @@ hi += lo1 >> 16; if ( lo1 < lo3 ) - hi += 0x10000UL; + hi += (FT_UInt32)0x10000UL; val = (FT_Fixed)hi; @@ -433,7 +433,7 @@ if ( shift > 0 ) { - FT_Int32 half = 1L << ( shift - 1 ); + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; diff --git a/lib/3rdparty/freetype/src/base/rules.mk b/lib/3rdparty/freetype/src/base/rules.mk index d6e441254b7..10f578abc8c 100644 --- a/lib/3rdparty/freetype/src/base/rules.mk +++ b/lib/3rdparty/freetype/src/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,8 +21,6 @@ # BASE_EXT_OBJ: A list of base layer extensions, i.e., components found # in `freetype/src/base' which are not compiled within the # base layer proper. -# -# BASE_H is defined in freetype.mk to simplify the dependency rules. BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) @@ -35,17 +33,25 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # All files listed here should be included in `ftbase.c' (for a `single' # build). # -BASE_SRC := $(BASE_DIR)/ftcalc.c \ +BASE_SRC := $(BASE_DIR)/ftadvanc.c \ + $(BASE_DIR)/ftcalc.c \ $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ - $(BASE_DIR)/ftnames.c \ $(BASE_DIR)/ftobjs.c \ $(BASE_DIR)/ftoutln.c \ $(BASE_DIR)/ftrfork.c \ + $(BASE_DIR)/ftsnames.c \ $(BASE_DIR)/ftstream.c \ $(BASE_DIR)/fttrigon.c \ $(BASE_DIR)/ftutil.c + +ifneq ($(ftmac_c),) + BASE_SRC += $(BASE_DIR)/$(ftmac_c) +endif + +BASE_H := $(BASE_DIR)/ftbase.h + # Base layer `extensions' sources # # An extension is added to the library file as a separate object. It is @@ -77,13 +83,13 @@ BASE_SRC_S := $(BASE_DIR)/ftbase.c # Base layer - single object build # -$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) +$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) $(BASE_H) $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BASE_SRC_S)) # Multiple objects build + extensions # -$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) +$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) $(BASE_H) $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) diff --git a/lib/3rdparty/freetype/src/bdf/bdf.h b/lib/3rdparty/freetype/src/bdf/bdf.h index 1b64426aad6..561b4158a51 100644 --- a/lib/3rdparty/freetype/src/bdf/bdf.h +++ b/lib/3rdparty/freetype/src/bdf/bdf.h @@ -114,8 +114,8 @@ FT_BEGIN_HEADER union { char* atom; - long int32; - unsigned long card32; + long l; + unsigned long ul; } value; /* Value of the property. */ @@ -160,7 +160,7 @@ FT_BEGIN_HEADER typedef struct _hashnode_ { const char* key; - void* data; + size_t data; } _hashnode, *hashnode; diff --git a/lib/3rdparty/freetype/src/bdf/bdfdrivr.c b/lib/3rdparty/freetype/src/bdf/bdfdrivr.c index 74cc2f1b8bf..631ec460e7c 100644 --- a/lib/3rdparty/freetype/src/bdf/bdfdrivr.c +++ b/lib/3rdparty/freetype/src/bdf/bdfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 by + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -53,7 +53,7 @@ THE SOFTWARE. typedef struct BDF_CMapRec_ { FT_CMapRec cmap; - FT_UInt num_encodings; + FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */ BDF_encoding_el* encodings; } BDF_CMapRec, *BDF_CMap; @@ -92,8 +92,8 @@ THE SOFTWARE. { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_encoding_el* encodings = cmap->encodings; - FT_UInt min, max, mid; - FT_UInt result = 0; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ min = 0; @@ -101,7 +101,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; mid = ( min + max ) >> 1; @@ -131,9 +131,9 @@ THE SOFTWARE. { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_encoding_el* encodings = cmap->encodings; - FT_UInt min, max, mid; - FT_UInt32 charcode = *acharcode + 1; - FT_UInt result = 0; + FT_ULong min, max, mid; /* num_encodings */ + FT_UShort result = 0; /* encodings->glyph */ + FT_ULong charcode = *acharcode + 1; min = 0; @@ -141,7 +141,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; /* same as BDF_encoding_el.enc */ mid = ( min + max ) >> 1; @@ -169,7 +169,14 @@ THE SOFTWARE. } Exit: - *acharcode = charcode; + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; return result; } @@ -181,7 +188,9 @@ THE SOFTWARE. bdf_cmap_init, bdf_cmap_done, bdf_cmap_char_index, - bdf_cmap_char_next + bdf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -194,9 +203,8 @@ THE SOFTWARE. bdf_font_t* font = bdf->bdffont; bdf_property_t* prop; - int nn, len; - char* strings[4] = { NULL, NULL, NULL, NULL }; - int lengths[4]; + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t nn, len, lengths[4]; face->style_flags = 0; @@ -282,7 +290,7 @@ THE SOFTWARE. /* add_style_name and setwidth_name */ if ( nn == 0 || nn == 3 ) { - int mm; + size_t mm; for ( mm = 0; mm < len; mm++ ) @@ -302,10 +310,15 @@ THE SOFTWARE. FT_CALLBACK_DEF( void ) BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ { - BDF_Face face = (BDF_Face)bdfface; - FT_Memory memory = FT_FACE_MEMORY( face ); + BDF_Face face = (BDF_Face)bdfface; + FT_Memory memory; + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + bdf_free_font( face->bdffont ); FT_FREE( face->en_table ); @@ -419,7 +432,7 @@ THE SOFTWARE. prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 ); + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); else bsize->width = (FT_Short)( bsize->height * 2/3 ); @@ -427,21 +440,21 @@ THE SOFTWARE. if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = - (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); else bsize->size = bsize->width << 6; prop = bdf_get_font_property( font, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.int32 << 6; + bsize->y_ppem = (FT_Short)prop->value.l << 6; prop = bdf_get_font_property( font, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.int32; + resolution_x = (FT_Short)prop->value.l; prop = bdf_get_font_property( font, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.int32; + resolution_y = (FT_Short)prop->value.l; if ( bsize->y_ppem == 0 ) { @@ -472,7 +485,12 @@ THE SOFTWARE. (face->en_table[n]).glyph = (FT_Short)n; if ( cur[n].encoding == font->default_char ) - face->default_glyph = n; + { + if ( n < FT_UINT_MAX ) + face->default_glyph = (FT_UInt)n; + else + FT_TRACE1(( "idx %d is too large for this system\n", n )); + } } } @@ -608,7 +626,7 @@ THE SOFTWARE. switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( bsize->y_ppem + 32 ) >> 6 ) + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) error = BDF_Err_Ok; break; @@ -664,7 +682,10 @@ THE SOFTWARE. bitmap->rows = glyph.bbx.height; bitmap->width = glyph.bbx.width; - bitmap->pitch = glyph.bpr; + if ( glyph.bpr > INT_MAX ) + FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", + glyph.bpr )); + bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ /* note: we don't allocate a new array to hold the bitmap; */ /* we can simply point to it */ @@ -736,13 +757,23 @@ THE SOFTWARE. break; case BDF_INTEGER: + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "bdf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = prop->value.int32; + aproperty->u.integer = (FT_Int32)prop->value.l; break; case BDF_CARDINAL: + if ( prop->value.ul > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "bdf_get_bdf_property: " )); + FT_TRACE1(( "too large cardinal 0x%x is truncated\n" )); + } aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; - aproperty->u.cardinal = prop->value.card32; + aproperty->u.cardinal = (FT_UInt32)prop->value.ul; break; default: diff --git a/lib/3rdparty/freetype/src/bdf/bdfdrivr.h b/lib/3rdparty/freetype/src/bdf/bdfdrivr.h index 86f40ee4af5..db7093bb45f 100644 --- a/lib/3rdparty/freetype/src/bdf/bdfdrivr.h +++ b/lib/3rdparty/freetype/src/bdf/bdfdrivr.h @@ -36,6 +36,10 @@ THE SOFTWARE. FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + typedef struct BDF_encoding_el_ { diff --git a/lib/3rdparty/freetype/src/bdf/bdflib.c b/lib/3rdparty/freetype/src/bdf/bdflib.c index 512cd62c3ec..5fa5868c715 100644 --- a/lib/3rdparty/freetype/src/bdf/bdflib.c +++ b/lib/3rdparty/freetype/src/bdf/bdflib.c @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 * Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a @@ -281,7 +281,7 @@ static FT_Error hash_insert( char* key, - void* data, + size_t data, hashtable* ht, FT_Memory memory ) { @@ -415,18 +415,18 @@ static FT_Error - _bdf_list_ensure( _bdf_list_t* list, - int num_items ) + _bdf_list_ensure( _bdf_list_t* list, + unsigned long num_items ) /* same as _bdf_list_t.used */ { FT_Error error = BDF_Err_Ok; - if ( num_items > (int)list->size ) + if ( num_items > list->size ) { - int oldsize = list->size; - int newsize = oldsize + ( oldsize >> 1 ) + 4; - int bigsize = FT_INT_MAX / sizeof ( char* ); - FT_Memory memory = list->memory; + unsigned long oldsize = list->size; /* same as _bdf_list_t.size */ + unsigned long newsize = oldsize + ( oldsize >> 1 ) + 4; + unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) ); + FT_Memory memory = list->memory; if ( oldsize == bigsize ) @@ -614,8 +614,8 @@ { _bdf_line_func_t cb; unsigned long lineno, buf_size; - int refill, bytes, hold, to_skip; - int start, end, cursor, avail; + int refill, hold, to_skip; + ptrdiff_t bytes, start, end, cursor, avail; char* buf = 0; FT_Memory memory = stream->memory; FT_Error error = BDF_Err_Ok; @@ -648,8 +648,8 @@ { if ( refill ) { - bytes = (int)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, - (FT_ULong)(buf_size - cursor) ); + bytes = (ptrdiff_t)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, + (FT_ULong)(buf_size - cursor) ); avail = cursor + bytes; cursor = 0; refill = 0; @@ -971,7 +971,7 @@ int format, bdf_font_t* font ) { - unsigned long n; + size_t n; bdf_property_t* p; FT_Memory memory = font->memory; FT_Error error = BDF_Err_Ok; @@ -991,7 +991,9 @@ p = font->user_props + font->nuser_props; FT_ZERO( p ); - n = (unsigned long)( ft_strlen( name ) + 1 ); + n = ft_strlen( name ) + 1; + if ( n > FT_ULONG_MAX ) + return BDF_Err_Invalid_Argument; if ( FT_NEW_ARRAY( p->name, n ) ) goto Exit; @@ -1003,7 +1005,7 @@ n = _num_bdf_properties + font->nuser_props; - error = hash_insert( p->name, (void *)n, &(font->proptbl), memory ); + error = hash_insert( p->name, n, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -1018,8 +1020,8 @@ bdf_get_property( char* name, bdf_font_t* font ) { - hashnode hn; - unsigned long propid; + hashnode hn; + size_t propid; if ( name == 0 || *name == 0 ) @@ -1028,7 +1030,7 @@ if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) return 0; - propid = (unsigned long)hn->data; + propid = hn->data; if ( propid >= _num_bdf_properties ) return font->user_props + ( propid - _num_bdf_properties ); @@ -1131,11 +1133,11 @@ _bdf_set_default_spacing( bdf_font_t* font, bdf_options_t* opts ) { - unsigned long len; - char name[256]; - _bdf_list_t list; - FT_Memory memory; - FT_Error error = BDF_Err_Ok; + size_t len; + char name[256]; + _bdf_list_t list; + FT_Memory memory; + FT_Error error = BDF_Err_Ok; if ( font == 0 || font->name == 0 || font->name[0] == 0 ) @@ -1150,7 +1152,7 @@ font->spacing = opts->font_spacing; - len = (unsigned long)( ft_strlen( font->name ) + 1 ); + len = ft_strlen( font->name ) + 1; /* Limit ourselves to 256 characters in the font name. */ if ( len >= 256 ) { @@ -1261,7 +1263,7 @@ char* name, char* value ) { - unsigned long propid; + size_t propid; hashnode hn; bdf_property_t *prop, *fp; FT_Memory memory = font->memory; @@ -1273,7 +1275,7 @@ { /* The property already exists in the font, so simply replace */ /* the value of the property with the current value. */ - fp = font->props + (unsigned long)hn->data; + fp = font->props + hn->data; switch ( fp->format ) { @@ -1289,11 +1291,11 @@ break; case BDF_INTEGER: - fp->value.int32 = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value, 0, 10 ); break; case BDF_CARDINAL: - fp->value.card32 = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value, 0, 10 ); break; default: @@ -1335,7 +1337,7 @@ font->props_size++; } - propid = (unsigned long)hn->data; + propid = hn->data; if ( propid >= _num_bdf_properties ) prop = font->user_props + ( propid - _num_bdf_properties ); else @@ -1359,11 +1361,11 @@ break; case BDF_INTEGER: - fp->value.int32 = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value, 0, 10 ); break; case BDF_CARDINAL: - fp->value.card32 = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value, 0, 10 ); break; } @@ -1372,7 +1374,7 @@ if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) { /* Add the property to the font property table. */ error = hash_insert( fp->name, - (void *)font->props_used, + font->props_used, (hashtable *)font->internal, memory ); if ( error ) @@ -1387,13 +1389,19 @@ /* present, and the SPACING property should override the default */ /* spacing. */ if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) - font->default_char = fp->value.int32; + font->default_char = fp->value.l; else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) - font->font_ascent = fp->value.int32; + font->font_ascent = fp->value.l; else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) - font->font_descent = fp->value.int32; + font->font_descent = fp->value.l; else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) { + if ( !fp->value.atom ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' ) font->spacing = BDF_PROPORTIONAL; else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' ) @@ -2038,7 +2046,7 @@ p->memory = 0; { /* setup */ - unsigned long i; + size_t i; bdf_property_t* prop; @@ -2048,7 +2056,7 @@ for ( i = 0, prop = (bdf_property_t*)_bdf_properties; i < _num_bdf_properties; i++, prop++ ) { - error = hash_insert( prop->name, (void *)i, + error = hash_insert( prop->name, i, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -2072,6 +2080,7 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + /* at this point, `p->font' can't be NULL */ p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) @@ -2465,7 +2474,7 @@ hn = hash_lookup( name, (hashtable *)font->internal ); - return hn ? ( font->props + (unsigned long)hn->data ) : 0; + return hn ? ( font->props + hn->data ) : 0; } diff --git a/lib/3rdparty/freetype/src/bdf/module.mk b/lib/3rdparty/freetype/src/bdf/module.mk index dfaa2744ebe..fe06ae8e064 100644 --- a/lib/3rdparty/freetype/src/bdf/module.mk +++ b/lib/3rdparty/freetype/src/bdf/module.mk @@ -27,7 +27,7 @@ FTMODULE_H_COMMANDS += BDF_DRIVER define BDF_DRIVER -$(OPEN_DRIVER)bdf_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, bdf_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/bdf/rules.mk b/lib/3rdparty/freetype/src/bdf/rules.mk index 25d98e55b07..6ff1614ddec 100644 --- a/lib/3rdparty/freetype/src/bdf/rules.mk +++ b/lib/3rdparty/freetype/src/bdf/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 2001, 2002, 2003 by +# Copyright (C) 2001, 2002, 2003, 2008 by # Francesco Zappa Nardelli # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,7 +29,7 @@ # bdf driver directory # -BDF_DIR := $(SRC_DIR)/bdf +BDF_DIR := $(SRC_DIR)/bdf BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) @@ -44,7 +44,8 @@ BDF_DRV_SRC := $(BDF_DIR)/bdflib.c \ # bdf driver headers # BDF_DRV_H := $(BDF_DIR)/bdf.h \ - $(BDF_DIR)/bdfdrivr.h + $(BDF_DIR)/bdfdrivr.h \ + $(BDF_DIR)/bdferror.h # bdf driver object(s) # diff --git a/lib/3rdparty/freetype/src/cache/ftcbasic.c b/lib/3rdparty/freetype/src/cache/ftcbasic.c index f2e62297d5c..ebc8871ccc0 100644 --- a/lib/3rdparty/freetype/src/cache/ftcbasic.c +++ b/lib/3rdparty/freetype/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,15 +17,17 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_CACHE_H #include "ftcglyph.h" #include "ftcimage.h" #include "ftcsbits.h" -#include FT_INTERNAL_MEMORY_H #include "ftccback.h" #include "ftcerror.h" +#define FT_COMPONENT trace_cache + #ifdef FT_CONFIG_OPTION_OLD_INTERNALS @@ -140,8 +142,18 @@ error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, &face ); + + if ( error || !face ) + return result; + + if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs ) + { + FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " )); + FT_TRACE1(( "in this face, truncated\n", face->num_glyphs )); + } + if ( !error ) - result = face->num_glyphs; + result = (FT_UInt)face->num_glyphs; return result; } @@ -304,7 +316,7 @@ FTC_Node *anode ) { FTC_BasicQueryRec query; - FTC_INode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_Error error; FT_UInt32 hash; @@ -320,13 +332,13 @@ if ( anode ) *anode = NULL; -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU ) /* * This one is a major hack used to detect whether we are passed a * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one. */ - if ( type->width >= 0x10000 ) + if ( (FT_ULong)type->width >= 0x10000L ) { FTC_OldImageDesc desc = (FTC_OldImageDesc)type; @@ -341,10 +353,16 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; query.attrs.scaler.height = type->height; - query.attrs.load_flags = type->flags; + query.attrs.load_flags = (FT_UInt)type->flags; } query.attrs.scaler.pixel = 1; @@ -365,7 +383,7 @@ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, FTC_GQUERY( &query ), - (FTC_Node*) &node ); + &node ); #endif if ( !error ) { @@ -373,8 +391,8 @@ if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } } @@ -394,7 +412,7 @@ FTC_Node *anode ) { FTC_BasicQueryRec query; - FTC_INode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_Error error; FT_UInt32 hash; @@ -410,8 +428,15 @@ if ( anode ) *anode = NULL; + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler = scaler[0]; - query.attrs.load_flags = load_flags; + query.attrs.load_flags = (FT_UInt)load_flags; hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; @@ -428,8 +453,8 @@ if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } } @@ -438,7 +463,7 @@ } - + #ifdef FT_CONFIG_OPTION_OLD_INTERNALS /* yet another backwards-legacy structure */ @@ -630,7 +655,7 @@ { FT_Error error; FTC_BasicQueryRec query; - FTC_SNode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_UInt32 hash; @@ -643,12 +668,12 @@ *ansbit = NULL; -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS +#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU ) /* This one is a major hack used to detect whether we are passed a * regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one. */ - if ( type->width >= 0x10000 ) + if ( (FT_ULong)type->width >= 0x10000L ) { FTC_OldImageDesc desc = (FTC_OldImageDesc)type; @@ -663,10 +688,16 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ { + if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; query.attrs.scaler.height = type->height; - query.attrs.load_flags = type->flags; + query.attrs.load_flags = (FT_UInt)type->flags; } query.attrs.scaler.pixel = 1; @@ -690,17 +721,18 @@ hash, gindex, FTC_GQUERY( &query ), - (FTC_Node*)&node ); + &node ); #endif if ( error ) goto Exit; - *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } Exit: @@ -720,7 +752,7 @@ { FT_Error error; FTC_BasicQueryRec query; - FTC_SNode node = 0; /* make compiler happy */ + FTC_Node node = 0; /* make compiler happy */ FT_UInt32 hash; @@ -733,8 +765,15 @@ *ansbit = NULL; + /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */ + if ( load_flags > FT_UINT_MAX ) + { + FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" )); + FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) )); + } + query.attrs.scaler = scaler[0]; - query.attrs.load_flags = load_flags; + query.attrs.load_flags = (FT_UInt)load_flags; /* beware, the hash must be the same for all glyph ranges! */ hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + @@ -750,12 +789,13 @@ if ( error ) goto Exit; - *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); + *ansbit = FTC_SNODE( node )->sbits + + ( gindex - FTC_GNODE( node )->gindex ); if ( anode ) { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; + *anode = node; + node->ref_count++; } Exit: diff --git a/lib/3rdparty/freetype/src/cache/ftccache.c b/lib/3rdparty/freetype/src/cache/ftccache.c index f3e699c3850..463addd99be 100644 --- a/lib/3rdparty/freetype/src/cache/ftccache.c +++ b/lib/3rdparty/freetype/src/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,9 @@ #include "ftccback.h" #include "ftcerror.h" +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + #define FTC_HASH_MAX_LOAD 2 #define FTC_HASH_MIN_LOAD 1 @@ -93,9 +96,9 @@ for (;;) { FTC_Node node, *pnode; - FT_UInt p = cache->p; - FT_UInt mask = cache->mask; - FT_UInt count = mask + p + 1; /* number of buckets */ + FT_UFast p = cache->p; + FT_UFast mask = cache->mask; + FT_UFast count = mask + p + 1; /* number of buckets */ /* do we need to shrink the buckets array? */ @@ -153,7 +156,7 @@ /* do we need to expand the buckets array? */ else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) { - FT_UInt old_index = p + mask; + FT_UFast old_index = p + mask; FTC_Node* pold; @@ -216,7 +219,7 @@ if ( node == NULL ) { - FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" )); + FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); return; } @@ -273,7 +276,7 @@ /* find node's cache */ if ( node->cache_index >= manager->num_caches ) { - FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif @@ -283,7 +286,7 @@ #ifdef FT_DEBUG_ERROR if ( cache == NULL ) { - FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); + FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif @@ -302,7 +305,7 @@ #if 0 /* check, just in case of general corruption :-) */ if ( manager->num_nodes == 0 ) - FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n", + FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n", manager->num_nodes )); #endif } @@ -347,7 +350,7 @@ { FTC_Manager manager = cache->manager; FT_UFast i; - FT_UInt count; + FT_UFast count; count = cache->p + cache->mask + 1; diff --git a/lib/3rdparty/freetype/src/cache/ftccache.h b/lib/3rdparty/freetype/src/cache/ftccache.h index 8c0a7c94fe6..2082bc4f4f0 100644 --- a/lib/3rdparty/freetype/src/cache/ftccache.h +++ b/lib/3rdparty/freetype/src/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,7 +91,7 @@ FT_BEGIN_HEADER FT_Pointer query, FTC_Cache cache ); - typedef FT_ULong + typedef FT_Offset (*FTC_Node_WeightFunc)( FTC_Node node, FTC_Cache cache ); @@ -121,7 +121,7 @@ FT_BEGIN_HEADER FTC_Node_CompareFunc node_remove_faceid; FTC_Node_FreeFunc node_free; - FT_UInt cache_size; + FT_Offset cache_size; FTC_Cache_InitFunc cache_init; FTC_Cache_DoneFunc cache_done; @@ -202,7 +202,7 @@ FT_BEGIN_HEADER FTC_Cache _cache = FTC_CACHE(cache); \ FT_UInt32 _hash = (FT_UInt32)(hash); \ FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ - FT_UInt _idx; \ + FT_UFast _idx; \ \ \ error = 0; \ @@ -246,8 +246,7 @@ FT_BEGIN_HEADER error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ _Ok: \ - _pnode = (FTC_Node*)(void*)&(node); \ - *_pnode = _node; \ + node = _node; \ FT_END_STMNT #else /* !FTC_INLINE */ diff --git a/lib/3rdparty/freetype/src/cache/ftccback.h b/lib/3rdparty/freetype/src/cache/ftccback.h index 86e72a7514f..4d0818db277 100644 --- a/lib/3rdparty/freetype/src/cache/ftccback.h +++ b/lib/3rdparty/freetype/src/cache/ftccback.h @@ -36,7 +36,7 @@ FT_Pointer gquery, FTC_Cache cache ); - FT_LOCAL( FT_ULong ) + FT_LOCAL( FT_Offset ) ftc_inode_weight( FTC_Node inode, FTC_Cache cache ); @@ -50,7 +50,7 @@ FT_Pointer gquery, FTC_Cache cache ); - FT_LOCAL( FT_ULong ) + FT_LOCAL( FT_Offset ) ftc_snode_weight( FTC_Node snode, FTC_Cache cache ); diff --git a/lib/3rdparty/freetype/src/cache/ftccmap.c b/lib/3rdparty/freetype/src/cache/ftccmap.c index aa59307f489..a802b0557c7 100644 --- a/lib/3rdparty/freetype/src/cache/ftccmap.c +++ b/lib/3rdparty/freetype/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include "ftcmanag.h" #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H -#include FT_TRUETYPE_IDS_H #include "ftccback.h" #include "ftcerror.h" @@ -86,9 +85,9 @@ #define FTC_CMAP_INDICES_MAX 128 /* compute a query/node hash */ -#define FTC_CMAP_HASH( faceid, index, charcode ) \ - ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \ - ( (char_code) / FTC_CMAP_INDICES_MAX ) ) +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( (charcode) / FTC_CMAP_INDICES_MAX ) ) /* the charmap query */ typedef struct FTC_CMapQueryRec_ @@ -175,7 +174,7 @@ /* compute the weight of a given cmap node */ - FT_CALLBACK_DEF( FT_ULong ) + FT_CALLBACK_DEF( FT_Offset ) ftc_cmap_node_weight( FTC_Node cnode, FTC_Cache cache ) { @@ -284,15 +283,27 @@ { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; - FTC_CMapNode node; + FTC_Node node; FT_Error error; FT_UInt gindex = 0; FT_UInt32 hash; + FT_Int no_cmap_change = 0; + if ( cmap_index < 0 ) + { + /* Treat a negative cmap index as a special value, meaning that you */ + /* don't want to change the FT_Face's character map through this */ + /* call. This can be useful if the face requester callback already */ + /* sets the face's charmap to the appropriate value. */ + + no_cmap_change = 1; + cmap_index = 0; + } + if ( !cache ) { - FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); + FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); return 0; } @@ -311,7 +322,7 @@ * Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf', * which contains more than 5 charmaps. */ - if ( cmap_index >= 16 ) + if ( cmap_index >= 16 && !no_cmap_change ) { FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; @@ -362,18 +373,21 @@ FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else - error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); + error = FTC_Cache_Lookup( cache, hash, &query, &node ); #endif if ( error ) goto Exit; - FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); + FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < + FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ - if ( (FT_UInt)( char_code - node->first >= FTC_CMAP_INDICES_MAX ) ) + if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= + FTC_CMAP_INDICES_MAX ) ) return 0; - gindex = node->indices[char_code - node->first]; + gindex = FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; @@ -381,7 +395,9 @@ gindex = 0; - error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); + error = FTC_Manager_LookupFace( cache->manager, + FTC_CMAP_NODE( node )->face_id, + &face ); if ( error ) goto Exit; @@ -393,16 +409,18 @@ old = face->charmap; cmap = face->charmaps[cmap_index]; - if ( old != cmap ) + if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); - if ( old != cmap ) + if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, old ); } - node->indices[char_code - node->first] = (FT_UShort)gindex; + FTC_CMAP_NODE( node )->indices[char_code - + FTC_CMAP_NODE( node )->first] + = (FT_UShort)gindex; } Exit: diff --git a/lib/3rdparty/freetype/src/cache/ftcglyph.c b/lib/3rdparty/freetype/src/cache/ftcglyph.c index 5c03abe0552..a9ab0c319f7 100644 --- a/lib/3rdparty/freetype/src/cache/ftcglyph.c +++ b/lib/3rdparty/freetype/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006 by */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,8 +20,6 @@ #include FT_CACHE_H #include "ftcglyph.h" #include FT_ERRORS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H #include "ftccback.h" #include "ftcerror.h" @@ -73,8 +71,8 @@ FT_UNUSED( cache ); - return FT_BOOL( gnode->family == gquery->family && - gnode->gindex == gquery->gindex ); + return FT_BOOL( gnode->family == gquery->family && + gnode->gindex == gquery->gindex ); } diff --git a/lib/3rdparty/freetype/src/cache/ftcglyph.h b/lib/3rdparty/freetype/src/cache/ftcglyph.h index 87a4199bfd8..c18f9c3af31 100644 --- a/lib/3rdparty/freetype/src/cache/ftcglyph.h +++ b/lib/3rdparty/freetype/src/cache/ftcglyph.h @@ -277,12 +277,14 @@ FT_BEGIN_HEADER FTC_GCache _gcache = FTC_GCACHE( cache ); \ FTC_GQuery _gquery = (FTC_GQuery)( query ); \ FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ + FTC_MruNode _mrunode; \ \ \ _gquery->gindex = (gindex); \ \ FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ - _gquery->family, error ); \ + _mrunode, error ); \ + _gquery->family = FTC_FAMILY( _mrunode ); \ if ( !error ) \ { \ FTC_Family _gqfamily = _gquery->family; \ @@ -303,11 +305,10 @@ FT_BEGIN_HEADER #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ gindex, query, node, error ) \ FT_BEGIN_STMNT \ - void* _n = &(node); \ - \ \ error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ - FTC_GQUERY( query ), (FTC_Node*)_n ); \ + FTC_GQUERY( query ), node ); \ + \ FT_END_STMNT #endif /* !FTC_INLINE */ diff --git a/lib/3rdparty/freetype/src/cache/ftcimage.c b/lib/3rdparty/freetype/src/cache/ftcimage.c index 15d4e80c8c3..417daf2aaea 100644 --- a/lib/3rdparty/freetype/src/cache/ftcimage.c +++ b/lib/3rdparty/freetype/src/cache/ftcimage.c @@ -103,12 +103,12 @@ } - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) ftc_inode_weight( FTC_Node ftcinode, FTC_Cache ftccache ) { FTC_INode inode = (FTC_INode)ftcinode; - FT_ULong size = 0; + FT_Offset size = 0; FT_Glyph glyph = inode->glyph; FT_UNUSED( ftccache ); @@ -151,7 +151,7 @@ #if 0 - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) FTC_INode_Weight( FTC_INode inode ) { return ftc_inode_weight( FTC_NODE( inode ), NULL ); diff --git a/lib/3rdparty/freetype/src/cache/ftcmanag.c b/lib/3rdparty/freetype/src/cache/ftcmanag.c index 9d7347c3dfd..f2a298e7d90 100644 --- a/lib/3rdparty/freetype/src/cache/ftcmanag.c +++ b/lib/3rdparty/freetype/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,10 @@ #include "ftccback.h" #include "ftcerror.h" +#ifdef FT_CONFIG_OPTION_PIC +#error "cache system does not support PIC yet" +#endif + #undef FT_COMPONENT #define FT_COMPONENT trace_cache @@ -78,6 +82,8 @@ } FTC_SizeNodeRec, *FTC_SizeNode; +#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) ) + FT_CALLBACK_DEF( void ) ftc_size_node_done( FTC_MruNode ftcnode, @@ -176,12 +182,12 @@ FTC_Scaler scaler, FT_Size *asize ) { - FT_Error error; - FTC_SizeNode node; + FT_Error error; + FTC_MruNode mrunode; if ( asize == NULL ) - return FTC_Err_Bad_Argument; + return FTC_Err_Invalid_Argument; *asize = NULL; @@ -191,14 +197,14 @@ #ifdef FTC_INLINE FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, - node, error ); + mrunode, error ); #else - error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node ); + error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode ); #endif if ( !error ) - *asize = node->size; + *asize = FTC_SIZE_NODE( mrunode )->size; return error; } @@ -220,6 +226,8 @@ } FTC_FaceNodeRec, *FTC_FaceNode; +#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) ) + FT_CALLBACK_DEF( FT_Error ) ftc_face_node_init( FTC_MruNode ftcnode, @@ -301,12 +309,12 @@ FTC_FaceID face_id, FT_Face *aface ) { - FT_Error error; - FTC_FaceNode node; + FT_Error error; + FTC_MruNode mrunode; if ( aface == NULL ) - return FTC_Err_Bad_Argument; + return FTC_Err_Invalid_Argument; *aface = NULL; @@ -317,14 +325,14 @@ #ifdef FTC_INLINE FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, - node, error ); + mrunode, error ); #else - error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node ); + error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode ); #endif if ( !error ) - *aface = node->face; + *aface = FTC_FACE_NODE( mrunode )->face; return error; } @@ -476,8 +484,8 @@ if ( (FT_UInt)node->cache_index >= manager->num_caches ) - FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n", - node->cache_index )); + FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n", + node->cache_index )); else weight += cache->clazz.node_weight( node, cache ); @@ -486,8 +494,8 @@ } while ( node != first ); if ( weight != manager->cur_weight ) - FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", - manager->cur_weight, weight )); + FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", + manager->cur_weight, weight )); } /* check circular list */ @@ -505,9 +513,9 @@ } while ( node != first ); if ( count != manager->num_nodes ) - FT_ERROR(( - "FTC_Manager_Check: invalid cache node count %d instead of %d\n", - manager->num_nodes, count )); + FT_TRACE0(( "FTC_Manager_Check:" + " invalid cache node count %d instead of %d\n", + manager->num_nodes, count )); } } @@ -534,9 +542,9 @@ #ifdef FT_DEBUG_ERROR FTC_Manager_Check( manager ); - FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n", - manager->cur_weight, manager->max_weight, - manager->num_nodes )); + FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n", + manager->cur_weight, manager->max_weight, + manager->num_nodes )); #endif if ( manager->cur_weight < manager->max_weight || first == NULL ) @@ -579,8 +587,8 @@ if ( manager->num_caches >= FTC_MAX_CACHES ) { error = FTC_Err_Too_Many_Caches; - FT_ERROR(( "%s: too many registered caches\n", - "FTC_Manager_Register_Cache" )); + FT_ERROR(( "FTC_Manager_RegisterCache:" + " too many registered caches\n" )); goto Exit; } @@ -608,7 +616,8 @@ } Exit: - *acache = cache; + if ( acache ) + *acache = cache; return error; } @@ -660,7 +669,9 @@ /* this will remove all FTC_SizeNode that correspond to * the face_id as well */ - FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id ); + FTC_MruList_RemoveSelection( &manager->faces, + (FTC_MruNode_CompareFunc)NULL, + face_id ); for ( nn = 0; nn < manager->num_caches; nn++ ) FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); diff --git a/lib/3rdparty/freetype/src/cache/ftcmru.c b/lib/3rdparty/freetype/src/cache/ftcmru.c index 3a6c625afa5..9944b58980d 100644 --- a/lib/3rdparty/freetype/src/cache/ftcmru.c +++ b/lib/3rdparty/freetype/src/cache/ftcmru.c @@ -4,7 +4,7 @@ /* */ /* FreeType MRU support (body). */ /* */ -/* Copyright 2003, 2004, 2006 by */ +/* Copyright 2003, 2004, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -46,7 +46,7 @@ { if ( cnode == node ) { - fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" ); + fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" ); exit( 2 ); } cnode = cnode->next; @@ -94,7 +94,7 @@ } while ( cnode != first ); - fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" ); + fprintf( stderr, "FTC_MruNode_Up: invalid action\n" ); exit( 2 ); Ok: } @@ -141,7 +141,7 @@ } while ( cnode != first ); - fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" ); + fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" ); exit( 2 ); Ok: } diff --git a/lib/3rdparty/freetype/src/cache/ftcmru.h b/lib/3rdparty/freetype/src/cache/ftcmru.h index c8f0c6ef6e3..5739439f450 100644 --- a/lib/3rdparty/freetype/src/cache/ftcmru.h +++ b/lib/3rdparty/freetype/src/cache/ftcmru.h @@ -107,7 +107,7 @@ FT_BEGIN_HEADER typedef struct FTC_MruListClassRec_ { - FT_UInt node_size; + FT_Offset node_size; FTC_MruNode_CompareFunc node_compare; FTC_MruNode_InitFunc node_init; FTC_MruNode_ResetFunc node_reset; @@ -163,7 +163,7 @@ FT_BEGIN_HEADER FT_BEGIN_STMNT \ FTC_MruNode* _pfirst = &(list)->nodes; \ FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ - FTC_MruNode _first, _node, *_pnode; \ + FTC_MruNode _first, _node; \ \ \ error = 0; \ @@ -180,8 +180,7 @@ FT_BEGIN_HEADER if ( _node != _first ) \ FTC_MruNode_Up( _pfirst, _node ); \ \ - _pnode = (FTC_MruNode*)(void*)&(node); \ - *_pnode = _node; \ + node = _node; \ goto _MruOk; \ } \ _node = _node->next; \ diff --git a/lib/3rdparty/freetype/src/cache/ftcsbits.c b/lib/3rdparty/freetype/src/cache/ftcsbits.c index 72f139d565b..60d46aa7a06 100644 --- a/lib/3rdparty/freetype/src/cache/ftcsbits.c +++ b/lib/3rdparty/freetype/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,9 @@ #include "ftccback.h" #include "ftcerror.h" +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + /*************************************************************************/ /*************************************************************************/ @@ -129,13 +132,13 @@ FT_Int temp; FT_GlyphSlot slot = face->glyph; FT_Bitmap* bitmap = &slot->bitmap; - FT_Int xadvance, yadvance; + FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) { - FT_ERROR(( "%s: glyph loaded didn't return a bitmap!\n", - "ftc_snode_load" )); + FT_TRACE0(( "ftc_snode_load:" + " glyph loaded didn't return a bitmap\n" )); goto BadGlyph; } @@ -263,7 +266,7 @@ } - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) ftc_snode_weight( FTC_Node ftcsnode, FTC_Cache cache ) { @@ -271,7 +274,7 @@ FT_UInt count = snode->count; FTC_SBit sbit = snode->sbits; FT_Int pitch; - FT_ULong size; + FT_Offset size; FT_UNUSED( cache ); @@ -300,7 +303,7 @@ #if 0 - FT_LOCAL_DEF( FT_ULong ) + FT_LOCAL_DEF( FT_Offset ) FTC_SNode_Weight( FTC_SNode snode ) { return ftc_snode_weight( FTC_NODE( snode ), NULL ); diff --git a/lib/3rdparty/freetype/src/cache/rules.mk b/lib/3rdparty/freetype/src/cache/rules.mk index 457dec848df..ed75a6a91fd 100644 --- a/lib/3rdparty/freetype/src/cache/rules.mk +++ b/lib/3rdparty/freetype/src/cache/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001, 2003, 2004, 2006 by +# Copyright 2000, 2001, 2003, 2004, 2006, 2008 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -26,7 +26,7 @@ CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) # CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ $(CACHE_DIR)/ftccache.c \ - $(CACHE_DIR)/ftccmap.c \ + $(CACHE_DIR)/ftccmap.c \ $(CACHE_DIR)/ftcglyph.c \ $(CACHE_DIR)/ftcimage.c \ $(CACHE_DIR)/ftcmanag.c \ @@ -35,12 +35,14 @@ CACHE_DRV_SRC := $(CACHE_DIR)/ftcbasic.c \ # Cache driver headers # -CACHE_DRV_H := $(CACHE_DIR)/ftccback.h \ +CACHE_DRV_H := $(CACHE_DIR)/ftccache.h \ + $(CACHE_DIR)/ftccback.h \ $(CACHE_DIR)/ftcerror.h \ $(CACHE_DIR)/ftcglyph.h \ $(CACHE_DIR)/ftcimage.h \ $(CACHE_DIR)/ftcmanag.h \ - $(CACHE_DIR)/ftcmru.h + $(CACHE_DIR)/ftcmru.h \ + $(CACHE_DIR)/ftcsbits.h # Cache driver object(s) diff --git a/lib/3rdparty/freetype/src/cff/Jamfile b/lib/3rdparty/freetype/src/cff/Jamfile index 6d0bb1b8679..6705d3cfdb7 100644 --- a/lib/3rdparty/freetype/src/cff/Jamfile +++ b/lib/3rdparty/freetype/src/cff/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cff ; if $(FT2_MULTI) { - _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap ; + _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap cffpic ; } else { diff --git a/lib/3rdparty/freetype/src/cff/cff.c b/lib/3rdparty/freetype/src/cff/cff.c index e6d8954c9ab..fccfd442f5d 100644 --- a/lib/3rdparty/freetype/src/cff/cff.c +++ b/lib/3rdparty/freetype/src/cff/cff.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "cffpic.c" #include "cffdrivr.c" #include "cffparse.c" #include "cffload.c" diff --git a/lib/3rdparty/freetype/src/cff/cffcmap.c b/lib/3rdparty/freetype/src/cff/cffcmap.c index fffc5fc550d..46d603e3a89 100644 --- a/lib/3rdparty/freetype/src/cff/cffcmap.c +++ b/lib/3rdparty/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,7 +65,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) cff_cmap_encoding_char_next( CFF_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -99,16 +99,16 @@ } - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - cff_cmap_encoding_class_rec = - { + FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, sizeof ( CFF_CMapStdRec ), (FT_CMap_InitFunc) cff_cmap_encoding_init, (FT_CMap_DoneFunc) cff_cmap_encoding_done, (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next - }; + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + + NULL, NULL, NULL, NULL, NULL + ) /*************************************************************************/ @@ -192,7 +192,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) cff_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { @@ -205,16 +205,15 @@ } - FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec - cff_cmap_unicode_class_rec = - { + FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, sizeof ( PS_UnicodesRec ), (FT_CMap_InitFunc) cff_cmap_unicode_init, (FT_CMap_DoneFunc) cff_cmap_unicode_done, (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next - }; + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + NULL, NULL, NULL, NULL, NULL + ) /* END */ diff --git a/lib/3rdparty/freetype/src/cff/cffcmap.h b/lib/3rdparty/freetype/src/cff/cffcmap.h index 3809b85611f..3f7f67bbe05 100644 --- a/lib/3rdparty/freetype/src/cff/cffcmap.h +++ b/lib/3rdparty/freetype/src/cff/cffcmap.h @@ -43,8 +43,7 @@ FT_BEGIN_HEADER } CFF_CMapStdRec; - FT_CALLBACK_TABLE const FT_CMap_ClassRec - cff_cmap_encoding_class_rec; + FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec) /*************************************************************************/ @@ -57,8 +56,7 @@ FT_BEGIN_HEADER /* unicode (synthetic) cmaps */ - FT_CALLBACK_TABLE const FT_CMap_ClassRec - cff_cmap_unicode_class_rec; + FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/cff/cffdrivr.c b/lib/3rdparty/freetype/src/cff/cffdrivr.c index 952e88e39f2..dad0b65d8b1 100644 --- a/lib/3rdparty/freetype/src/cff/cffdrivr.c +++ b/lib/3rdparty/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,21 +21,25 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H +#include FT_SERVICE_CID_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_TT_CMAP_H #include "cffdrivr.h" #include "cffgload.h" #include "cffload.h" #include "cffcmap.h" +#include "cffparse.h" #include "cfferrs.h" +#include "cffpic.h" #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_GLYPH_DICT_H + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -151,7 +155,7 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { - FT_Error error; + FT_Error error; CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; CFF_Size size = (CFF_Size)cffsize; @@ -163,10 +167,10 @@ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + /* reset the size object if necessary */ if ( load_flags & FT_LOAD_NO_SCALE ) size = NULL; - /* reset the size object if necessary */ if ( size ) { /* these two objects must have the same parent */ @@ -184,10 +188,39 @@ } - /* - * GLYPH DICT SERVICE - * - */ + FT_CALLBACK_DEF( FT_Error ) + cff_get_advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ) + { + FT_UInt nn; + FT_Error error = CFF_Err_Ok; + FT_GlyphSlot slot = face->glyph; + + + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + + for ( nn = 0; nn < count; nn++ ) + { + error = Load_Glyph( slot, face->size, start + nn, flags ); + if ( error ) + break; + + advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) + ? slot->linearVertAdvance + : slot->linearHoriAdvance; + } + + return error; + } + + + /* + * GLYPH DICT SERVICE + * + */ static FT_Error cff_get_glyph_name( CFF_Face face, @@ -206,10 +239,10 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "cff_get_glyph_name:" )); - FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -226,8 +259,8 @@ FT_FREE( gname ); error = CFF_Err_Ok; - Exit: - return error; + Exit: + return error; } @@ -277,17 +310,16 @@ } - static const FT_Service_GlyphDictRec cff_service_glyph_dict = - { + FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict, (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index, - }; + (FT_GlyphDict_NameIndexFunc)cff_get_name_index + ) - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Int cff_ps_has_glyph_names( FT_Face face ) @@ -306,9 +338,10 @@ if ( cff && cff->font_info == NULL ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; - PS_FontInfoRec *font_info; - FT_Memory memory = face->root.memory; + CFF_FontRecDict dict = &cff->top_font.font_dict; + PS_FontInfoRec *font_info; + FT_Memory memory = face->root.memory; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) @@ -316,19 +349,19 @@ font_info->version = cff_index_get_sid_string( &cff->string_index, dict->version, - cff->psnames ); + psnames ); font_info->notice = cff_index_get_sid_string( &cff->string_index, dict->notice, - cff->psnames ); + psnames ); font_info->full_name = cff_index_get_sid_string( &cff->string_index, dict->full_name, - cff->psnames ); + psnames ); font_info->family_name = cff_index_get_sid_string( &cff->string_index, dict->family_name, - cff->psnames ); + psnames ); font_info->weight = cff_index_get_sid_string( &cff->string_index, dict->weight, - cff->psnames ); + psnames ); font_info->italic_angle = dict->italic_angle; font_info->is_fixed_pitch = dict->is_fixed_pitch; font_info->underline_position = (FT_Short)dict->underline_position; @@ -337,19 +370,40 @@ cff->font_info = font_info; } - *afont_info = *cff->font_info; + if ( cff ) + *afont_info = *cff->font_info; Fail: return error; } - static const FT_Service_PsInfoRec cff_service_ps_info = - { + FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info, (PS_GetFontInfoFunc) cff_ps_get_font_info, + (PS_GetFontExtraFunc) NULL, (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ - }; + ) + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + cff_get_ps_name( CFF_Face face ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + return (const char*)cff->font_name; + } + + + FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name, + (FT_PsName_GetFunc)cff_get_ps_name + ) /* @@ -368,15 +422,16 @@ { FT_CMap cmap = FT_CMAP( charmap ); FT_Error error = CFF_Err_Ok; + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Library library = FT_FACE_LIBRARY( face ); cmap_info->language = 0; + cmap_info->format = 0; - if ( cmap->clazz != &cff_cmap_encoding_class_rec && - cmap->clazz != &cff_cmap_unicode_class_rec ) + if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET && + cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET ) { - FT_Face face = FT_CMAP_FACE( cmap ); - FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, @@ -391,10 +446,143 @@ } - static const FT_Service_TTCMapsRec cff_service_get_cmap_info = - { + FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info, (TT_CMap_Info_GetFunc)cff_get_cmap_info - }; + ) + + + /* + * CID INFO SERVICE + * + */ + static FT_Error + cff_get_ros( CFF_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( registry ) + { + if ( cff->registry == NULL ) + cff->registry = cff_index_get_sid_string( &cff->string_index, + dict->cid_registry, + psnames ); + *registry = cff->registry; + } + + if ( ordering ) + { + if ( cff->ordering == NULL ) + cff->ordering = cff_index_get_sid_string( &cff->string_index, + dict->cid_ordering, + psnames ); + *ordering = cff->ordering; + } + + /* + * XXX: According to Adobe TechNote #5176, the supplement in CFF + * can be a real number. We truncate it to fit public API + * since freetype-2.3.6. + */ + if ( supplement ) + { + if ( dict->cid_supplement < FT_INT_MIN || + dict->cid_supplement > FT_INT_MAX ) + FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", + dict->cid_supplement )); + *supplement = (FT_Int)dict->cid_supplement; + } + } + + Fail: + return error; + } + + + static FT_Error + cff_get_is_cid( CFF_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + *is_cid = 0; + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry != 0xFFFFU ) + *is_cid = 1; + } + + return error; + } + + + static FT_Error + cff_get_cid_from_glyph_index( CFF_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff; + + + cff = (CFF_Font)face->extra.data; + + if ( cff ) + { + FT_UInt c; + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if ( glyph_index > cff->num_glyphs ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + c = cff->charset.sids[glyph_index]; + + if ( cid ) + *cid = c; + } + + Fail: + return error; + } + + + FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info, + (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + ) /*************************************************************************/ @@ -408,18 +596,24 @@ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ - - static const FT_ServiceDescRec cff_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, - { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, + FT_DEFINE_SERVICEDESCREC6(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC5(cff_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, + FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET + ) #endif - { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, - { NULL, NULL } - }; - FT_CALLBACK_DEF( FT_Module_Interface ) cff_get_interface( FT_Module driver, /* CFF_Driver */ @@ -429,10 +623,13 @@ FT_Module_Interface result; - result = ft_service_list_lookup( cff_services, module_interface ); + result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface ); if ( result != NULL ) return result; + if ( !driver ) + return NULL; + /* we pass our request to the `sfnt' module */ sfnt = FT_Get_Module( driver->library, "sfnt" ); @@ -442,11 +639,13 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec cff_driver_class = - { - /* begin with the FT_Module_Class fields */ - { +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define CFF_SIZE_SELECT cff_size_select +#else +#define CFF_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(cff_driver_class, FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, @@ -461,7 +660,6 @@ cff_driver_init, cff_driver_done, cff_get_interface, - }, /* now the specific driver fields */ sizeof( TT_FaceRec ), @@ -475,25 +673,19 @@ cff_slot_init, cff_slot_done, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - ft_stub_set_char_sizes, - ft_stub_set_pixel_sizes, -#endif + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ Load_Glyph, cff_get_kerning, 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + cff_get_advances, /* FT_Face_GetAdvancesFunc */ cff_size_request, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - cff_size_select -#else - 0 /* FT_Size_SelectFunc */ -#endif - }; + CFF_SIZE_SELECT + ) /* END */ diff --git a/lib/3rdparty/freetype/src/cff/cffdrivr.h b/lib/3rdparty/freetype/src/cff/cffdrivr.h index 553848c0a9c..50e8138701e 100644 --- a/lib/3rdparty/freetype/src/cff/cffdrivr.h +++ b/lib/3rdparty/freetype/src/cff/cffdrivr.h @@ -27,8 +27,7 @@ FT_BEGIN_HEADER - FT_CALLBACK_TABLE - const FT_Driver_ClassRec cff_driver_class; + FT_DECLARE_DRIVER( cff_driver_class ) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/cff/cffgload.c b/lib/3rdparty/freetype/src/cff/cffgload.c index d354227e250..9330c058823 100644 --- a/lib/3rdparty/freetype/src/cff/cffgload.c +++ b/lib/3rdparty/freetype/src/cff/cffgload.c @@ -4,7 +4,8 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,11 +19,9 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_OUTLINE_H -#include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include "cffobjs.h" @@ -110,6 +109,15 @@ cff_op_callgsubr, cff_op_return, + /* Type 1 opcodes: invalid but seen in real life */ + cff_op_hsbw, + cff_op_closepath, + cff_op_callothersubr, + cff_op_pop, + cff_op_seac, + cff_op_sbw, + cff_op_setcurrentpoint, + /* do not remove */ cff_op_max @@ -120,6 +128,11 @@ #define CFF_COUNT_EXACT 0x40 #define CFF_COUNT_CLEAR_STACK 0x20 + /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ + /* used for checking the width and requested numbers of arguments */ + /* only; they are set to zero afterwards */ + + /* the other two flags are informative only and unused currently */ static const FT_Byte cff_argument_counts[] = { @@ -187,7 +200,15 @@ 1, /* callsubr */ 1, - 0 + 0, + + 2, /* hsbw */ + 0, + 0, + 0, + 5, /* seac */ + 4, /* sbw */ + 2 /* setcurrentpoint */ }; @@ -222,6 +243,8 @@ /* */ /* glyph :: The current glyph object. */ /* */ + /* hinting :: Whether hinting is active. */ + /* */ static void cff_builder_init( CFF_Builder* builder, TT_Face face, @@ -251,17 +274,14 @@ if ( hinting && size ) { - builder->hints_globals = size->root.internal; + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + builder->hints_globals = (void *)internal->topfont; builder->hints_funcs = glyph->root.internal->glyph_hints; } } - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; @@ -306,17 +326,23 @@ /* subroutines. */ /* */ /* <Input> */ - /* num_subrs :: The number of glyph subroutines. */ + /* in_charstring_type :: The `CharstringType' value of the top DICT */ + /* dictionary. */ + /* */ + /* num_subrs :: The number of glyph subroutines. */ /* */ /* <Return> */ /* The bias value. */ static FT_Int - cff_compute_bias( FT_UInt num_subrs ) + cff_compute_bias( FT_Int in_charstring_type, + FT_UInt num_subrs ) { FT_Int result; - if ( num_subrs < 1240 ) + if ( in_charstring_type == 1 ) + result = 0; + else if ( num_subrs < 1240 ) result = 107; else if ( num_subrs < 33900U ) result = 1131; @@ -339,11 +365,15 @@ /* decoder :: A pointer to the glyph builder to initialize. */ /* */ /* <Input> */ - /* face :: The current face object. */ + /* face :: The current face object. */ /* */ - /* size :: The current size object. */ + /* size :: The current size object. */ /* */ - /* slot :: The current glyph object. */ + /* slot :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + /* hint_mode :: The hinting mode. */ /* */ FT_LOCAL_DEF( void ) cff_decoder_init( CFF_Decoder* decoder, @@ -363,26 +393,32 @@ cff_builder_init( &decoder->builder, face, size, slot, hinting ); /* initialize Type2 decoder */ + decoder->cff = cff; decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; - decoder->globals_bias = cff_compute_bias( decoder->num_globals ); + decoder->globals_bias = cff_compute_bias( + cff->top_font.font_dict.charstring_type, + decoder->num_globals ); decoder->hint_mode = hint_mode; } - /* this function is used to select the locals subrs array */ + /* this function is used to select the subfont */ + /* and the locals subrs array */ FT_LOCAL_DEF( FT_Error ) cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, FT_UInt glyph_index ) { - CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data; - CFF_SubFont sub = &cff->top_font; - FT_Error error = CFF_Err_Ok; + CFF_Builder *builder = &decoder->builder; + CFF_Font cff = (CFF_Font)builder->face->extra.data; + CFF_SubFont sub = &cff->top_font; + FT_Error error = CFF_Err_Ok; /* manage CID fonts */ - if ( cff->num_subfonts >= 1 ) + if ( cff->num_subfonts ) { FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); @@ -394,12 +430,29 @@ goto Exit; } + FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index, fd_index )); + sub = cff->subfonts[fd_index]; + + if ( builder->hints_funcs && size ) + { + CFF_Internal internal = (CFF_Internal)size->root.internal; + + + /* for CFFs without subfonts, this value has already been set */ + builder->hints_globals = (void *)internal->subfonts[fd_index]; + } } +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE4(( "glyph index %d:\n", glyph_index )); +#endif decoder->num_locals = sub->num_local_subrs; decoder->locals = sub->local_subrs; - decoder->locals_bias = cff_compute_bias( decoder->num_locals ); + decoder->locals_bias = cff_compute_bias( + decoder->cff->top_font.font_dict.charstring_type, + decoder->num_locals ); decoder->glyph_width = sub->private_dict.default_width; decoder->nominal_width = sub->private_dict.nominal_width; @@ -437,8 +490,6 @@ point->x = x >> 16; point->y = y >> 16; *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; @@ -517,27 +568,24 @@ cff_builder_close_contour( CFF_Builder* builder ) { FT_Outline* outline = builder->current; + FT_Int first; if ( !outline ) return; - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ if ( outline->n_points > 1 ) { - FT_Int first = 0; FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - /* `delete' last point only if it coincides with the first */ /* point and if it is not a control point (which can happen). */ if ( p1->x == p2->x && p1->y == p2->y ) @@ -546,8 +594,18 @@ } if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether begin point and last point are the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } } @@ -637,7 +695,7 @@ data.length = length; face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object,&data ); + face->root.internal->incremental_interface->object, &data ); } else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -653,6 +711,7 @@ static FT_Error cff_operator_seac( CFF_Decoder* decoder, + FT_Pos asb, FT_Pos adx, FT_Pos ady, FT_Int bchar, @@ -665,8 +724,18 @@ FT_Vector left_bearing, advance; FT_Byte* charstring; FT_ULong charstring_len; + FT_Pos glyph_width; + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return CFF_Err_Syntax_Error; + } + + adx += decoder->builder.left_bearing.x; + ady += decoder->builder.left_bearing.y; + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts don't necessarily have valid charsets. */ /* They use the character code, not the glyph index, in this case. */ @@ -687,8 +756,8 @@ if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "cff_operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "cff_operator_seac:" + " invalid seac character code arguments\n" )); return CFF_Err_Syntax_Error; } @@ -737,8 +806,11 @@ &charstring, &charstring_len ); if ( !error ) { + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -746,16 +818,17 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - /* Save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ + /* Save the left bearing, advance and glyph width of the base */ + /* character as they will be erased by the next load. */ left_bearing = builder->left_bearing; advance = builder->advance; + glyph_width = decoder->glyph_width; builder->left_bearing.x = 0; builder->left_bearing.y = 0; - builder->pos_x = adx; + builder->pos_x = adx - asb; builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ @@ -763,8 +836,11 @@ &charstring, &charstring_len ); if ( !error ) { + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -772,10 +848,11 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - /* Restore the left side bearing and advance width */ - /* of the base character. */ + /* Restore the left side bearing, advance and glyph width */ + /* of the base character. */ builder->left_bearing = left_bearing; builder->advance = advance; + decoder->glyph_width = glyph_width; builder->pos_x = 0; builder->pos_y = 0; @@ -817,6 +894,8 @@ FT_Pos x, y; FT_Fixed seed; FT_Fixed* stack; + FT_Int charstring_type = + decoder->cff->top_font.font_dict.charstring_type; T2_Hints_Funcs hinter; @@ -826,9 +905,10 @@ decoder->read_width = 1; /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)(char*)&seed ^ - (FT_Fixed)(char*)&decoder ^ - (FT_Fixed)(char*)&charstring_base; + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -883,18 +963,18 @@ ip += 2; } else if ( v < 247 ) - val = (FT_Long)v - 139; + val = (FT_Int32)v - 139; else if ( v < 251 ) { if ( ip >= limit ) goto Syntax_Error; - val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108; + val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; } else if ( v < 255 ) { if ( ip >= limit ) goto Syntax_Error; - val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108; + val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; } else { @@ -905,7 +985,8 @@ ( (FT_Int32)ip[2] << 8 ) | ip[3]; ip += 4; - shift = 0; + if ( charstring_type == 2 ) + shift = 0; } if ( decoder->top - stack >= CFF_MAX_OPERANDS ) goto Stack_Overflow; @@ -923,6 +1004,11 @@ } else { + /* The specification says that normally arguments are to be taken */ + /* from the bottom of the stack. However, this seems not to be */ + /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ + /* arguments similar to a PS interpreter. */ + FT_Fixed* args = decoder->top; FT_Int num_args = (FT_Int)( args - decoder->stack ); FT_Int req_args; @@ -954,6 +1040,9 @@ case 8: op = cff_op_rrcurveto; break; + case 9: + op = cff_op_closepath; + break; case 10: op = cff_op_callsubr; break; @@ -971,6 +1060,12 @@ case 0: op = cff_op_dotsection; break; + case 1: /* this is actually the Type1 vstem3 operator */ + op = cff_op_vstem; + break; + case 2: /* this is actually the Type1 hstem3 operator */ + op = cff_op_hstem; + break; case 3: op = cff_op_and; break; @@ -980,6 +1075,12 @@ case 5: op = cff_op_not; break; + case 6: + op = cff_op_seac; + break; + case 7: + op = cff_op_sbw; + break; case 8: op = cff_op_store; break; @@ -1004,6 +1105,12 @@ case 15: op = cff_op_eq; break; + case 16: + op = cff_op_callothersubr; + break; + case 17: + op = cff_op_pop; + break; case 18: op = cff_op_drop; break; @@ -1037,6 +1144,9 @@ case 30: op = cff_op_roll; break; + case 33: + op = cff_op_setcurrentpoint; + break; case 34: op = cff_op_hflex; break; @@ -1055,6 +1165,9 @@ } } break; + case 13: + op = cff_op_hsbw; + break; case 14: op = cff_op_endchar; break; @@ -1101,8 +1214,9 @@ op = cff_op_hvcurveto; break; default: - ; + break; } + if ( op == cff_op_unknown ) goto Syntax_Error; @@ -1110,8 +1224,6 @@ req_args = cff_argument_counts[op]; if ( req_args & CFF_COUNT_CHECK_WIDTH ) { - args = stack; - if ( num_args > 0 && decoder->read_width ) { /* If `nominal_width' is non-zero, the number is really a */ @@ -1145,7 +1257,7 @@ case cff_op_endchar: /* If there is a width specified for endchar, we either have */ /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( ( num_args == 5 ) || ( num_args == 1 ) ); + set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); break; default: @@ -1158,9 +1270,14 @@ decoder->glyph_width = decoder->nominal_width + ( stack[0] >> 16 ); + if ( decoder->width_only ) + { + /* we only want the advance width; stop here */ + break; + } + /* Consumed an argument. */ num_args--; - args++; } } @@ -1168,12 +1285,20 @@ req_args = 0; } - req_args &= 15; + req_args &= 0x000F; if ( num_args < req_args ) goto Stack_Underflow; args -= req_args; num_args -= req_args; + /* At this point, `args' points to the first argument of the */ + /* operand in case `req_args' isn't zero. Otherwise, we have */ + /* to adjust `args' manually. */ + + /* Note that we only pop arguments from the stack which we */ + /* really need and can digest so that we can continue in case */ + /* of superfluous stack elements. */ + switch ( op ) { case cff_op_hstem: @@ -1181,15 +1306,16 @@ case cff_op_hstemhm: case cff_op_vstemhm: /* the number of arguments is always even here */ - FT_TRACE4(( op == cff_op_hstem ? " hstem" : - ( op == cff_op_vstem ? " vstem" : - ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); + FT_TRACE4(( + op == cff_op_hstem ? " hstem\n" : + ( op == cff_op_vstem ? " vstem\n" : + ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); if ( hinter ) hinter->stems( hinter->hints, ( op == cff_op_hstem || op == cff_op_hstemhm ), num_args / 2, - args ); + args - ( num_args & ~1 ) ); decoder->num_hints += num_args / 2; args = stack; @@ -1209,7 +1335,7 @@ hinter->stems( hinter->hints, 0, num_args / 2, - args ); + args - ( num_args & ~1 ) ); decoder->num_hints += num_args / 2; } @@ -1232,12 +1358,14 @@ FT_UInt maskbyte; - FT_TRACE4(( " " )); + FT_TRACE4(( " (maskbytes: " )); for ( maskbyte = 0; maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3); maskbyte++, ip++ ) FT_TRACE4(( "0x%02X", *ip )); + + FT_TRACE4(( ")\n" )); } #else ip += ( decoder->num_hints + 7 ) >> 3; @@ -1248,44 +1376,44 @@ break; case cff_op_rmoveto: - FT_TRACE4(( " rmoveto" )); + FT_TRACE4(( " rmoveto\n" )); cff_builder_close_contour( builder ); builder->path_begun = 0; - x += args[0]; - y += args[1]; + x += args[-2]; + y += args[-1]; args = stack; break; case cff_op_vmoveto: - FT_TRACE4(( " vmoveto" )); + FT_TRACE4(( " vmoveto\n" )); cff_builder_close_contour( builder ); builder->path_begun = 0; - y += args[0]; + y += args[-1]; args = stack; break; case cff_op_hmoveto: - FT_TRACE4(( " hmoveto" )); + FT_TRACE4(( " hmoveto\n" )); cff_builder_close_contour( builder ); builder->path_begun = 0; - x += args[0]; + x += args[-1]; args = stack; break; case cff_op_rlineto: - FT_TRACE4(( " rlineto" )); + FT_TRACE4(( " rlineto\n" )); if ( cff_builder_start_point ( builder, x, y ) || check_points( builder, num_args / 2 ) ) goto Fail; - if ( num_args < 2 || num_args & 1 ) + if ( num_args < 2 ) goto Stack_Underflow; - args = stack; + args -= num_args & ~1; while ( args < decoder->top ) { x += args[0]; @@ -1302,8 +1430,11 @@ FT_Int phase = ( op == cff_op_hlineto ); - FT_TRACE4(( op == cff_op_hlineto ? " hlineto" - : " vlineto" )); + FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" + : " vlineto\n" )); + + if ( num_args < 1 ) + goto Stack_Underflow; if ( cff_builder_start_point ( builder, x, y ) || check_points( builder, num_args ) ) @@ -1328,125 +1459,164 @@ break; case cff_op_rrcurveto: - FT_TRACE4(( " rrcurveto" )); - - /* check number of arguments; must be a multiple of 6 */ - if ( num_args % 6 != 0 ) - goto Stack_Underflow; - - if ( cff_builder_start_point ( builder, x, y ) || - check_points( builder, num_args / 2 ) ) - goto Fail; - - args = stack; - while ( args < decoder->top ) { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args += 6; + FT_Int nargs; + + + FT_TRACE4(( " rrcurveto\n" )); + + if ( num_args < 6 ) + goto Stack_Underflow; + + nargs = num_args - num_args % 6; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, nargs / 2 ) ) + goto Fail; + + args -= nargs; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + } + args = stack; } - args = stack; break; case cff_op_vvcurveto: - FT_TRACE4(( " vvcurveto" )); - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args = stack; - if ( num_args & 1 ) { - x += args[0]; - args++; - num_args--; + FT_Int nargs; + + + FT_TRACE4(( " vvcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we reduce it to 4n+1 */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + + if ( nargs & 1 ) + { + x += args[0]; + args++; + nargs--; + } + + if ( check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; } - - if ( num_args % 4 != 0 ) - goto Stack_Underflow; - - if ( check_points( builder, 3 * ( num_args / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - y += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; break; case cff_op_hhcurveto: - FT_TRACE4(( " hhcurveto" )); - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args = stack; - if ( num_args & 1 ) { - y += args[0]; - args++; - num_args--; + FT_Int nargs; + + + FT_TRACE4(( " hhcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we reduce it to 4n+1 */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + if ( nargs & 1 ) + { + y += args[0]; + args++; + nargs--; + } + + if ( check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; } - - if ( num_args % 4 != 0 ) - goto Stack_Underflow; - - if ( check_points( builder, 3 * ( num_args / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; break; case cff_op_vhcurveto: case cff_op_hvcurveto: { FT_Int phase; + FT_Int nargs; - FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto" - : " hvcurveto" )); + FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" + : " hvcurveto\n" )); if ( cff_builder_start_point( builder, x, y ) ) goto Fail; - args = stack; - if ( num_args < 4 || ( num_args % 4 ) > 1 ) + if ( num_args < 4 ) goto Stack_Underflow; - if ( check_points( builder, ( num_args / 4 ) * 3 ) ) + /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ + /* we reduce it to the largest one which fits */ + + nargs = num_args - num_args % 4; + if ( num_args - nargs > 0 ) + nargs += 1; + + args -= nargs; + if ( check_points( builder, ( nargs / 4 ) * 3 ) ) goto Stack_Underflow; phase = ( op == cff_op_hvcurveto ); - while ( num_args >= 4 ) + while ( nargs >= 4 ) { - num_args -= 4; + nargs -= 4; if ( phase ) { x += args[0]; @@ -1455,7 +1625,7 @@ y += args[2]; cff_builder_add_point( builder, x, y, 0 ); y += args[3]; - if ( num_args == 1 ) + if ( nargs == 1 ) x += args[4]; cff_builder_add_point( builder, x, y, 1 ); } @@ -1467,7 +1637,7 @@ y += args[2]; cff_builder_add_point( builder, x, y, 0 ); x += args[3]; - if ( num_args == 1 ) + if ( nargs == 1 ) y += args[4]; cff_builder_add_point( builder, x, y, 1 ); } @@ -1480,19 +1650,23 @@ case cff_op_rlinecurve: { - FT_Int num_lines = ( num_args - 6 ) / 2; + FT_Int num_lines; + FT_Int nargs; - FT_TRACE4(( " rlinecurve" )); + FT_TRACE4(( " rlinecurve\n" )); - if ( num_args < 8 || ( num_args - 6 ) & 1 ) + if ( num_args < 8 ) goto Stack_Underflow; + nargs = num_args & ~1; + num_lines = ( nargs - 6 ) / 2; + if ( cff_builder_start_point( builder, x, y ) || check_points( builder, num_lines + 3 ) ) goto Fail; - args = stack; + args -= nargs; /* first, add the line segments */ while ( num_lines > 0 ) @@ -1520,19 +1694,24 @@ case cff_op_rcurveline: { - FT_Int num_curves = ( num_args - 2 ) / 6; + FT_Int num_curves; + FT_Int nargs; - FT_TRACE4(( " rcurveline" )); + FT_TRACE4(( " rcurveline\n" )); - if ( num_args < 8 || ( num_args - 2 ) % 6 ) + if ( num_args < 8 ) goto Stack_Underflow; + nargs = num_args - 2; + nargs = nargs - nargs % 6 + 2; + num_curves = ( nargs - 2 ) / 6; + if ( cff_builder_start_point ( builder, x, y ) || - check_points( builder, num_curves*3 + 2 ) ) + check_points( builder, num_curves * 3 + 2 ) ) goto Fail; - args = stack; + args -= nargs; /* first, add the curves */ while ( num_curves > 0 ) @@ -1563,18 +1742,16 @@ FT_Pos start_y; - FT_TRACE4(( " hflex1" )); + FT_TRACE4(( " hflex1\n" )); - args = stack; - - /* adding five more points; 4 control points, 1 on-curve point */ - /* make sure we have enough space for the start point if it */ + /* adding five more points: 4 control points, 1 on-curve point */ + /* -- make sure we have enough space for the start point if it */ /* needs to be added */ if ( cff_builder_start_point( builder, x, y ) || check_points( builder, 6 ) ) goto Fail; - /* Record the starting point's y position for later use */ + /* record the starting point's y position for later use */ start_y = y; /* first control point */ @@ -1616,9 +1793,7 @@ FT_Pos start_y; - FT_TRACE4(( " hflex" )); - - args = stack; + FT_TRACE4(( " hflex\n" )); /* adding six more points; 4 control points, 2 on-curve points */ if ( cff_builder_start_point( builder, x, y ) || @@ -1663,14 +1838,15 @@ case cff_op_flex1: { - FT_Pos start_x, start_y; /* record start x, y values for */ - /* alter use */ - FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; + FT_Fixed* temp; - FT_TRACE4(( " flex1" )); + FT_TRACE4(( " flex1\n" )); /* adding six more points; 4 control points, 2 on-curve points */ if ( cff_builder_start_point( builder, x, y ) || @@ -1684,21 +1860,20 @@ /* XXX: figure out whether this is supposed to be a horizontal */ /* or vertical flex; the Type 2 specification is vague... */ - args = stack; + temp = args; /* grab up to the last argument */ for ( count = 5; count > 0; count-- ) { - dx += args[0]; - dy += args[1]; - args += 2; + dx += temp[0]; + dy += temp[1]; + temp += 2; } - /* rewind */ - args = stack; - - if ( dx < 0 ) dx = -dx; - if ( dy < 0 ) dy = -dy; + if ( dx < 0 ) + dx = -dx; + if ( dy < 0 ) + dy = -dy; /* strange test, but here it is... */ horizontal = ( dx > dy ); @@ -1707,7 +1882,8 @@ { x += args[0]; y += args[1]; - cff_builder_add_point( builder, x, y, (FT_Bool)( count == 3 ) ); + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 3 ) ); args += 2; } @@ -1734,13 +1910,12 @@ FT_UInt count; - FT_TRACE4(( " flex" )); + FT_TRACE4(( " flex\n" )); if ( cff_builder_start_point( builder, x, y ) || check_points( builder, 6 ) ) goto Fail; - args = stack; for ( count = 6; count > 0; count-- ) { x += args[0]; @@ -1754,22 +1929,34 @@ } break; + case cff_op_seac: + FT_TRACE4(( " seac\n" )); + + error = cff_operator_seac( decoder, + args[0], args[1], args[2], + (FT_Int)( args[3] >> 16 ), + (FT_Int)( args[4] >> 16 ) ); + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + case cff_op_endchar: - FT_TRACE4(( " endchar" )); + FT_TRACE4(( " endchar\n" )); /* We are going to emulate the seac operator. */ - if ( num_args == 4 ) + if ( num_args >= 4 ) { /* Save glyph width so that the subglyphs don't overwrite it. */ FT_Pos glyph_width = decoder->glyph_width; - error = cff_operator_seac( decoder, - args[0], - args[1], - (FT_Int)( args[2] >> 16 ), - (FT_Int)( args[3] >> 16 ) ); - args += 4; + 0L, args[-4], args[-3], + (FT_Int)( args[-2] >> 16 ), + (FT_Int)( args[-1] >> 16 ) ); decoder->glyph_width = glyph_width; } @@ -1799,11 +1986,11 @@ } /* return now! */ - FT_TRACE4(( "\n\n" )); + FT_TRACE4(( "\n" )); return error; case cff_op_abs: - FT_TRACE4(( " abs" )); + FT_TRACE4(( " abs\n" )); if ( args[0] < 0 ) args[0] = -args[0]; @@ -1811,28 +1998,28 @@ break; case cff_op_add: - FT_TRACE4(( " add" )); + FT_TRACE4(( " add\n" )); args[0] += args[1]; args++; break; case cff_op_sub: - FT_TRACE4(( " sub" )); + FT_TRACE4(( " sub\n" )); args[0] -= args[1]; args++; break; case cff_op_div: - FT_TRACE4(( " div" )); + FT_TRACE4(( " div\n" )); args[0] = FT_DivFix( args[0], args[1] ); args++; break; case cff_op_neg: - FT_TRACE4(( " neg" )); + FT_TRACE4(( " neg\n" )); args[0] = -args[0]; args++; @@ -1843,7 +2030,7 @@ FT_Fixed Rand; - FT_TRACE4(( " rand" )); + FT_TRACE4(( " rand\n" )); Rand = seed; if ( Rand >= 0x8000L ) @@ -1858,14 +2045,14 @@ break; case cff_op_mul: - FT_TRACE4(( " mul" )); + FT_TRACE4(( " mul\n" )); args[0] = FT_MulFix( args[0], args[1] ); args++; break; case cff_op_sqrt: - FT_TRACE4(( " sqrt" )); + FT_TRACE4(( " sqrt\n" )); if ( args[0] > 0 ) { @@ -1890,7 +2077,7 @@ case cff_op_drop: /* nothing */ - FT_TRACE4(( " drop" )); + FT_TRACE4(( " drop\n" )); break; @@ -1899,7 +2086,7 @@ FT_Fixed tmp; - FT_TRACE4(( " exch" )); + FT_TRACE4(( " exch\n" )); tmp = args[0]; args[0] = args[1]; @@ -1913,7 +2100,7 @@ FT_Int idx = (FT_Int)( args[0] >> 16 ); - FT_TRACE4(( " index" )); + FT_TRACE4(( " index\n" )); if ( idx < 0 ) idx = 0; @@ -1930,7 +2117,7 @@ FT_Int idx = (FT_Int)( args[1] >> 16 ); - FT_TRACE4(( " roll" )); + FT_TRACE4(( " roll\n" )); if ( count <= 0 ) count = 1; @@ -1972,10 +2159,10 @@ break; case cff_op_dup: - FT_TRACE4(( " dup" )); + FT_TRACE4(( " dup\n" )); args[1] = args[0]; - args++; + args += 2; break; case cff_op_put: @@ -1984,9 +2171,9 @@ FT_Int idx = (FT_Int)( args[1] >> 16 ); - FT_TRACE4(( " put" )); + FT_TRACE4(( " put\n" )); - if ( idx >= 0 && idx < decoder->len_buildchar ) + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) decoder->buildchar[idx] = val; } break; @@ -1997,9 +2184,9 @@ FT_Fixed val = 0; - FT_TRACE4(( " get" )); + FT_TRACE4(( " get\n" )); - if ( idx >= 0 && idx < decoder->len_buildchar ) + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) val = decoder->buildchar[idx]; args[0] = val; @@ -2008,18 +2195,97 @@ break; case cff_op_store: - FT_TRACE4(( " store ")); + FT_TRACE4(( " store\n")); goto Unimplemented; case cff_op_load: - FT_TRACE4(( " load" )); + FT_TRACE4(( " load\n" )); goto Unimplemented; case cff_op_dotsection: /* this operator is deprecated and ignored by the parser */ - FT_TRACE4(( " dotsection" )); + FT_TRACE4(( " dotsection\n" )); + break; + + case cff_op_closepath: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " closepath (invalid op)\n" )); + + args = stack; + break; + + case cff_op_hsbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " hsbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = 0; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y; + args = stack; + break; + + case cff_op_sbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " sbw (invalid op)\n" )); + + decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = args[1]; + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; + args = stack; + break; + + case cff_op_setcurrentpoint: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); + + x = decoder->builder.pos_x + args[0]; + y = decoder->builder.pos_y + args[1]; + args = stack; + break; + + case cff_op_callothersubr: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " callothersubr (invalid op)\n" )); + + /* subsequent `pop' operands should add the arguments, */ + /* this is the implementation described for `unknown' other */ + /* subroutines in the Type1 spec. */ + args -= 2 + ( args[-2] >> 16 ); + break; + + case cff_op_pop: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " pop (invalid op)\n" )); + + args++; break; case cff_op_and: @@ -2027,7 +2293,7 @@ FT_Fixed cond = args[0] && args[1]; - FT_TRACE4(( " and" )); + FT_TRACE4(( " and\n" )); args[0] = cond ? 0x10000L : 0; args++; @@ -2039,7 +2305,7 @@ FT_Fixed cond = args[0] || args[1]; - FT_TRACE4(( " or" )); + FT_TRACE4(( " or\n" )); args[0] = cond ? 0x10000L : 0; args++; @@ -2051,7 +2317,7 @@ FT_Fixed cond = !args[0]; - FT_TRACE4(( " eq" )); + FT_TRACE4(( " eq\n" )); args[0] = cond ? 0x10000L : 0; args++; @@ -2063,7 +2329,7 @@ FT_Fixed cond = ( args[2] <= args[3] ); - FT_TRACE4(( " ifelse" )); + FT_TRACE4(( " ifelse\n" )); if ( !cond ) args[0] = args[1]; @@ -2077,12 +2343,12 @@ decoder->locals_bias ); - FT_TRACE4(( " callsubr(%d)", idx )); + FT_TRACE4(( " callsubr(%d)\n", idx )); if ( idx >= decoder->num_locals ) { - FT_ERROR(( "cff_decoder_parse_charstrings:" )); - FT_ERROR(( " invalid local subr index\n" )); + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid local subr index\n" )); goto Syntax_Error; } @@ -2103,7 +2369,7 @@ if ( !zone->base || zone->limit == zone->base ) { FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs!\n" )); + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -2119,12 +2385,12 @@ decoder->globals_bias ); - FT_TRACE4(( " callgsubr(%d)", idx )); + FT_TRACE4(( " callgsubr(%d)\n", idx )); if ( idx >= decoder->num_globals ) { - FT_ERROR(( "cff_decoder_parse_charstrings:" )); - FT_ERROR(( " invalid global subr index\n" )); + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid global subr index\n" )); goto Syntax_Error; } @@ -2145,7 +2411,7 @@ if ( !zone->base || zone->limit == zone->base ) { FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs!\n" )); + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -2156,7 +2422,7 @@ break; case cff_op_return: - FT_TRACE4(( " return" )); + FT_TRACE4(( " return\n" )); if ( decoder->zone <= decoder->zones ) { @@ -2194,15 +2460,15 @@ return error; Syntax_Error: - FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); return CFF_Err_Invalid_File_Format; Stack_Underflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); return CFF_Err_Too_Few_Arguments; Stack_Overflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" )); + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); return CFF_Err_Stack_Overflow; } @@ -2260,7 +2526,7 @@ &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_prepare( &decoder, size, glyph_index ); if ( !error ) error = cff_decoder_parse_charstrings( &decoder, charstring, @@ -2290,23 +2556,30 @@ { FT_Error error; CFF_Decoder decoder; - TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; - CFF_Font cff = (CFF_Font)face->extra.data; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting, force_scaling; + CFF_Font cff = (CFF_Font)face->extra.data; FT_Matrix font_matrix; FT_Vector font_offset; + force_scaling = FALSE; + /* in a CID-keyed font, consider `glyph_index' as a CID and map */ /* it immediately to the real glyph_index -- if it isn't a */ /* subsetted font, glyph_indices and CIDs are identical, though */ if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && - cff->charset.cids ) + cff->charset.cids ) { - glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index ); - if ( glyph_index == 0 ) - return CFF_Err_Invalid_Argument; + /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */ + if ( glyph_index != 0 ) + { + glyph_index = cff_charset_cid_to_gindex( &cff->charset, + glyph_index ); + if ( glyph_index == 0 ) + return CFF_Err_Invalid_Argument; + } } else if ( glyph_index >= cff->num_glyphs ) return CFF_Err_Invalid_Argument; @@ -2389,6 +2662,36 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) return CFF_Err_Invalid_Argument; + /* if we have a CID subfont, use its matrix (which has already */ + /* been multiplied with the root matrix) */ + + /* this scaling is only relevant if the PS hinter isn't active */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, + glyph_index ); + + FT_ULong top_upm = cff->top_font.font_dict.units_per_em; + FT_ULong sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em; + + + font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; + font_offset = cff->subfonts[fd_index]->font_dict.font_offset; + + if ( top_upm != sub_upm ) + { + glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); + glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); + + force_scaling = TRUE; + } + } + else + { + font_matrix = cff->top_font.font_dict.font_matrix; + font_offset = cff->top_font.font_dict.font_offset; + } + glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -2405,15 +2708,18 @@ cff_decoder_init( &decoder, face, size, glyph, hinting, FT_LOAD_TARGET_MODE( load_flags ) ); + if ( load_flags & FT_LOAD_ADVANCE_ONLY ) + decoder.width_only = TRUE; + decoder.builder.no_recurse = - (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); /* now load the unscaled outline */ error = cff_get_glyph_data( face, glyph_index, &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_prepare( &decoder, size, glyph_index ); if ( !error ) { error = cff_decoder_parse_charstrings( &decoder, @@ -2458,44 +2764,31 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && + if ( !error && + face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = decoder.builder.left_bearing.x; - metrics.bearing_y = decoder.builder.left_bearing.y; + metrics.bearing_y = 0; metrics.advance = decoder.builder.advance.x; + metrics.advance_v = decoder.builder.advance.y; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); + decoder.builder.left_bearing.x = metrics.bearing_x; - decoder.builder.left_bearing.y = metrics.bearing_y; decoder.builder.advance.x = metrics.advance; - decoder.builder.advance.y = 0; + decoder.builder.advance.y = metrics.advance_v; } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ if ( !error ) { - if ( cff->num_subfonts >= 1 ) - { - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, - glyph_index ); - - - font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; - font_offset = cff->subfonts[fd_index]->font_dict.font_offset; - } - else - { - font_matrix = cff->top_font.font_dict.font_matrix; - font_offset = cff->top_font.font_dict.font_offset; - } - /* Now, set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax. */ @@ -2526,9 +2819,14 @@ glyph->root.linearHoriAdvance = decoder.glyph_width; glyph->root.internal->glyph_transformed = 0; +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS has_vertical_info = FT_BOOL( face->vertical_info && face->vertical.number_Of_VMetrics > 0 && - face->vertical.long_metrics != 0 ); + face->vertical.long_metrics ); +#else + has_vertical_info = FT_BOOL( face->vertical_info && + face->vertical.number_Of_VMetrics > 0 ); +#endif /* get the vertical metrics from the vtmx table if we have one */ if ( has_vertical_info ) @@ -2565,7 +2863,6 @@ glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; - /* apply the font matrix */ if ( !( font_matrix.xx == 0x10000L && font_matrix.yy == 0x10000L && font_matrix.xy == 0 && @@ -2587,7 +2884,7 @@ FT_Vector_Transform( &advance, &font_matrix ); metrics->vertAdvance = advance.y + font_offset.y; - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) { /* scale the outline and the metrics */ FT_Int n; @@ -2620,10 +2917,14 @@ metrics->horiBearingY = cbox.yMax; if ( has_vertical_info ) - metrics->vertBearingX = -metrics->width / 2; - else - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + metrics->vertBearingX = metrics->horiBearingX - + metrics->horiAdvance / 2; + else + { + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } } diff --git a/lib/3rdparty/freetype/src/cff/cffgload.h b/lib/3rdparty/freetype/src/cff/cffgload.h index f67864a6925..38937be5c11 100644 --- a/lib/3rdparty/freetype/src/cff/cffgload.h +++ b/lib/3rdparty/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,9 @@ FT_BEGIN_HEADER -#define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 32 +#define CFF_MAX_TRANS_ELEMENTS 32 /*************************************************************************/ @@ -53,12 +54,6 @@ FT_BEGIN_HEADER /* */ /* current :: The current glyph outline. */ /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ @@ -92,11 +87,6 @@ FT_BEGIN_HEADER FT_Outline* base; FT_Outline* current; - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - FT_Pos pos_x; FT_Pos pos_y; @@ -146,9 +136,9 @@ FT_BEGIN_HEADER FT_Pos nominal_width; FT_Bool read_width; + FT_Bool width_only; FT_Int num_hints; - FT_Fixed* buildchar; - FT_Int len_buildchar; + FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; FT_UInt num_locals; FT_UInt num_globals; @@ -164,6 +154,8 @@ FT_BEGIN_HEADER FT_Render_Mode hint_mode; + FT_Bool seac; + } CFF_Decoder; @@ -177,6 +169,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, FT_UInt glyph_index ); #if 0 /* unused until we support pure CFF fonts */ diff --git a/lib/3rdparty/freetype/src/cff/cffload.c b/lib/3rdparty/freetype/src/cff/cffload.c index dd2f1133dca..64d13957235 100644 --- a/lib/3rdparty/freetype/src/cff/cffload.c +++ b/lib/3rdparty/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,7 @@ #if 1 + static const FT_UShort cff_isoadobe_charset[229] = { 0, 1, 2, 3, 4, 5, 6, 7, @@ -175,13 +176,15 @@ 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378 }; -#endif + +#endif /* 1 */ FT_LOCAL_DEF( FT_UShort ) cff_get_standard_encoding( FT_UInt charcode ) { - return (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0); + return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] + : 0 ); } @@ -316,7 +319,7 @@ static FT_Error cff_index_load_offsets( CFF_Index idx ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; FT_Stream stream = idx->stream; FT_Memory memory = stream->memory; @@ -399,6 +402,7 @@ old_offset = 1; for ( n = 0; n <= idx->count; n++ ) { + /* at this point, `idx->offsets' can't be NULL */ offset = idx->offsets[n]; if ( !offset ) offset = old_offset; @@ -732,6 +736,7 @@ { FT_Error error = FT_Err_Ok; FT_UInt i; + FT_Long j; FT_UShort max_cid = 0; @@ -746,8 +751,11 @@ if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) goto Exit; - for ( i = 0; i < num_glyphs; i++ ) - charset->cids[charset->sids[i]] = (FT_UShort)i; + /* When multiple GIDs map to the same CID, we choose the lowest */ + /* GID. This is not described in any spec, but it matches the */ + /* behaviour of recent Acroread versions. */ + for ( j = num_glyphs - 1; j >= 0 ; j-- ) + charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; charset->num_glyphs = num_glyphs; @@ -838,7 +846,20 @@ goto Exit; for ( j = 1; j < num_glyphs; j++ ) - charset->sids[j] = FT_GET_USHORT(); + { + FT_UShort sid = FT_GET_USHORT(); + + + /* this constant is given in the CFF specification */ + if ( sid < 65000L ) + charset->sids[j] = sid; + else + { + FT_TRACE0(( "cff_charset_load:" + " invalid SID value %d set to zero\n", sid )); + charset->sids[j] = 0; + } + } FT_FRAME_EXIT(); } @@ -871,6 +892,20 @@ goto Exit; } + /* check whether the range contains at least one valid glyph; */ + /* the constant is given in the CFF specification */ + if ( glyph_sid >= 65000L ) { + FT_ERROR(( "cff_charset_load: invalid SID range\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* try to rescue some of the SIDs if `nleft' is too large */ + if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) { + FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" )); + nleft = ( FT_UInt )( 65000L - 1L - glyph_sid ); + } + /* Fill in the range of sids -- `nleft + 1' glyphs. */ for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) charset->sids[j] = glyph_sid; @@ -879,7 +914,7 @@ break; default: - FT_ERROR(( "cff_charset_load: invalid table format!\n" )); + FT_ERROR(( "cff_charset_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -902,7 +937,7 @@ if ( num_glyphs > 229 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)!\n" )); + "predefined charset (Adobe ISO-Latin)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -920,7 +955,7 @@ if ( num_glyphs > 166 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert)!\n" )); + "predefined charset (Adobe Expert)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -938,7 +973,7 @@ if ( num_glyphs > 87 ) { FT_ERROR(( "cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe Expert Subset)!\n" )); + "predefined charset (Adobe Expert Subset)\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1123,7 +1158,7 @@ break; default: - FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1218,7 +1253,7 @@ break; default: - FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + FT_ERROR(( "cff_encoding_load: invalid table format\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1236,7 +1271,8 @@ CFF_Index idx, FT_UInt font_index, FT_Stream stream, - FT_ULong base_offset ) + FT_ULong base_offset, + FT_Library library ) { FT_Error error; CFF_ParserRec parser; @@ -1246,7 +1282,7 @@ CFF_Private priv = &font->private_dict; - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict ); + cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); /* set defaults */ FT_MEM_ZERO( top, sizeof ( *top ) ); @@ -1272,8 +1308,9 @@ top->cid_ordering = 0xFFFFU; top->cid_font_name = 0xFFFFU; - error = cff_index_access_element( idx, font_index, &dict, &dict_len ) || - cff_parser_run( &parser, dict, dict + dict_len ); + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + if ( !error ) + error = cff_parser_run( &parser, dict, dict + dict_len ); cff_index_forget_element( idx, &dict ); @@ -1296,7 +1333,7 @@ priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv ); + cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || FT_FRAME_ENTER( font->font_dict.private_size ) ) @@ -1349,9 +1386,11 @@ FT_LOCAL_DEF( FT_Error ) - cff_font_load( FT_Stream stream, + cff_font_load( FT_Library library, + FT_Stream stream, FT_Int face_index, - CFF_Font font ) + CFF_Font font, + FT_Bool pure_cff ) { static const FT_Frame_Field cff_header_fields[] = { @@ -1388,7 +1427,7 @@ font->header_size < 4 || font->absolute_offsize > 4 ) { - FT_TRACE2(( "[not a CFF font header!]\n" )); + FT_TRACE2(( "[not a CFF font header]\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -1426,7 +1465,8 @@ &font->font_dict_index, face_index, stream, - base_offset ); + base_offset, + library ); if ( error ) goto Exit; @@ -1456,7 +1496,7 @@ if ( fd_index.count > CFF_MAX_CID_FONTS ) { - FT_ERROR(( "cff_font_load: FD array too large in CID font\n" )); + FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); goto Fail_CID; } @@ -1474,7 +1514,7 @@ { sub = font->subfonts[idx]; error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset ); + stream, base_offset, library ); if ( error ) goto Fail_CID; } @@ -1497,7 +1537,7 @@ /* read the charstrings index now */ if ( dict->charstrings_offset == 0 ) { - FT_ERROR(( "cff_font_load: no charstrings offset!\n" )); + FT_ERROR(( "cff_font_load: no charstrings offset\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } @@ -1515,7 +1555,7 @@ /* read the Charset and Encoding tables if available */ if ( font->num_glyphs > 0 ) { - FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU ); + FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); error = cff_charset_load( &font->charset, font->num_glyphs, stream, @@ -1535,9 +1575,6 @@ if ( error ) goto Exit; } - else - /* CID-keyed fonts only need CIDs */ - FT_FREE( font->charset.sids ); } /* get the font name (/CIDFontName for CID-keyed fonts, */ @@ -1590,6 +1627,9 @@ FT_FREE( font->font_info ); } + FT_FREE( font->registry ); + FT_FREE( font->ordering ); + FT_FREE( font->global_subrs ); FT_FREE( font->font_name ); } diff --git a/lib/3rdparty/freetype/src/cff/cffload.h b/lib/3rdparty/freetype/src/cff/cffload.h index 068cbb58c23..2b313acf06e 100644 --- a/lib/3rdparty/freetype/src/cff/cffload.h +++ b/lib/3rdparty/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,9 +58,11 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - cff_font_load( FT_Stream stream, + cff_font_load( FT_Library library, + FT_Stream stream, FT_Int face_index, - CFF_Font font ); + CFF_Font font, + FT_Bool pure_cff ); FT_LOCAL( void ) cff_font_done( CFF_Font font ); diff --git a/lib/3rdparty/freetype/src/cff/cffobjs.c b/lib/3rdparty/freetype/src/cff/cffobjs.c index c02cf33fc8b..bd56c4ba11d 100644 --- a/lib/3rdparty/freetype/src/cff/cffobjs.c +++ b/lib/3rdparty/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,6 +30,7 @@ #include "cffload.h" #include "cffcmap.h" #include "cfferrs.h" +#include "cffpic.h" /*************************************************************************/ @@ -56,7 +57,7 @@ cff_size_get_globals_funcs( CFF_Size size ) { CFF_Face face = (CFF_Face)size->root.face; - CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_Font font = (CFF_Font)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; FT_Module module; @@ -72,23 +73,84 @@ FT_LOCAL_DEF( void ) cff_size_done( FT_Size cffsize ) /* CFF_Size */ { - CFF_Size size = (CFF_Size)cffsize; + CFF_Size size = (CFF_Size)cffsize; + CFF_Face face = (CFF_Face)size->root.face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)cffsize->internal; - if ( cffsize->internal ) + if ( internal ) { PSH_Globals_Funcs funcs; funcs = cff_size_get_globals_funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)cffsize->internal ); + { + FT_UInt i; - cffsize->internal = 0; + + funcs->destroy( internal->topfont ); + + for ( i = font->num_subfonts; i > 0; i-- ) + funcs->destroy( internal->subfonts[i - 1] ); + } + + /* `internal' is freed by destroy_size (in ftobjs.c) */ } } + /* CFF and Type 1 private dictionaries have slightly different */ + /* structures; we need to synthesize a Type 1 dictionary on the fly */ + + static void + cff_make_private_dict( CFF_SubFont subfont, + PS_Private priv ) + { + CFF_Private cpriv = &subfont->private_dict; + FT_UInt n, count; + + + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + count = priv->num_blue_values = cpriv->num_blue_values; + for ( n = 0; n < count; n++ ) + priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; + + count = priv->num_other_blues = cpriv->num_other_blues; + for ( n = 0; n < count; n++ ) + priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; + + count = priv->num_family_blues = cpriv->num_family_blues; + for ( n = 0; n < count; n++ ) + priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; + + count = priv->num_family_other_blues = cpriv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + + priv->blue_scale = cpriv->blue_scale; + priv->blue_shift = (FT_Int)cpriv->blue_shift; + priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; + + priv->standard_width[0] = (FT_UShort)cpriv->standard_width; + priv->standard_height[0] = (FT_UShort)cpriv->standard_height; + + count = priv->num_snap_widths = cpriv->num_snap_widths; + for ( n = 0; n < count; n++ ) + priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + + count = priv->num_snap_heights = cpriv->num_snap_heights; + for ( n = 0; n < count; n++ ) + priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; + + priv->force_bold = cpriv->force_bold; + priv->language_group = cpriv->language_group; + priv->lenIV = cpriv->lenIV; + } + + FT_LOCAL_DEF( FT_Error ) cff_size_init( FT_Size cffsize ) /* CFF_Size */ { @@ -99,68 +161,43 @@ if ( funcs ) { - PSH_Globals globals; - CFF_Face face = (CFF_Face)cffsize->face; - CFF_Font font = (CFF_FontRec *)face->extra.data; - CFF_SubFont subfont = &font->top_font; + CFF_Face face = (CFF_Face)cffsize->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal; - CFF_Private cpriv = &subfont->private_dict; PS_PrivateRec priv; + FT_Memory memory = cffsize->face->memory; + + FT_UInt i; - /* IMPORTANT: The CFF and Type1 private dictionaries have */ - /* slightly different structures; we need to */ - /* synthetize a type1 dictionary on the fly here. */ + if ( FT_NEW( internal ) ) + goto Exit; + cff_make_private_dict( &font->top_font, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->topfont ); + if ( error ) + goto Exit; + + for ( i = font->num_subfonts; i > 0; i-- ) { - FT_UInt n, count; + CFF_SubFont sub = font->subfonts[i - 1]; - FT_MEM_ZERO( &priv, sizeof ( priv ) ); - - count = priv.num_blue_values = cpriv->num_blue_values; - for ( n = 0; n < count; n++ ) - priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; - - count = priv.num_other_blues = cpriv->num_other_blues; - for ( n = 0; n < count; n++ ) - priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; - - count = priv.num_family_blues = cpriv->num_family_blues; - for ( n = 0; n < count; n++ ) - priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; - - count = priv.num_family_other_blues = cpriv->num_family_other_blues; - for ( n = 0; n < count; n++ ) - priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; - - priv.blue_scale = cpriv->blue_scale; - priv.blue_shift = (FT_Int)cpriv->blue_shift; - priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz; - - priv.standard_width[0] = (FT_UShort)cpriv->standard_width; - priv.standard_height[0] = (FT_UShort)cpriv->standard_height; - - count = priv.num_snap_widths = cpriv->num_snap_widths; - for ( n = 0; n < count; n++ ) - priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; - - count = priv.num_snap_heights = cpriv->num_snap_heights; - for ( n = 0; n < count; n++ ) - priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; - - priv.force_bold = cpriv->force_bold; - priv.language_group = cpriv->language_group; - priv.lenIV = cpriv->lenIV; + cff_make_private_dict( sub, &priv ); + error = funcs->create( cffsize->face->memory, &priv, + &internal->subfonts[i - 1] ); + if ( error ) + goto Exit; } - error = funcs->create( cffsize->face->memory, &priv, &globals ); - if ( !error ) - cffsize->internal = (FT_Size_Internal)(void*)globals; + cffsize->internal = (FT_Size_Internal)(void*)internal; } size->strike_index = 0xFFFFFFFFUL; + Exit: return error; } @@ -182,11 +219,42 @@ funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + { + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)face->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + return CFF_Err_Ok; } @@ -223,11 +291,42 @@ funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + { + CFF_Face cffface = (CFF_Face)size->face; + CFF_Font font = (CFF_Font)cffface->extra.data; + CFF_Internal internal = (CFF_Internal)size->internal; + + FT_ULong top_upm = font->top_font.font_dict.units_per_em; + FT_UInt i; + + + funcs->set_scale( internal->topfont, + size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); + for ( i = font->num_subfonts; i > 0; i-- ) + { + CFF_SubFont sub = font->subfonts[i - 1]; + FT_ULong sub_upm = sub->font_dict.units_per_em; + FT_Pos x_scale, y_scale; + + + if ( top_upm != sub_upm ) + { + x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); + y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); + } + else + { + x_scale = size->metrics.x_scale; + y_scale = size->metrics.y_scale; + } + + funcs->set_scale( internal->subfonts[i - 1], + x_scale, y_scale, 0, 0 ); + } + } + return CFF_Err_Ok; } @@ -249,7 +348,7 @@ cff_slot_init( FT_GlyphSlot slot ) { CFF_Face face = (CFF_Face)slot->face; - CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_Font font = (CFF_Font)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; @@ -270,7 +369,7 @@ } } - return 0; + return CFF_Err_Ok; } @@ -288,7 +387,9 @@ FT_String* result; - result = ft_mem_strdup( memory, source, &error ); + (void)FT_STRDUP( result, source ); + + FT_UNUSED( error ); return result; } @@ -308,6 +409,7 @@ PSHinter_Service pshinter; FT_Bool pure_cff = 1; FT_Bool sfnt_format = 0; + FT_Library library = cffface->driver->root.library; #if 0 @@ -319,14 +421,14 @@ goto Bad_Format; #else sfnt = (SFNT_Service)FT_Get_Module_Interface( - cffface->driver->root.library, "sfnt" ); + library, "sfnt" ); if ( !sfnt ) goto Bad_Format; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); pshinter = (PSHinter_Service)FT_Get_Module_Interface( - cffface->driver->root.library, "pshinter" ); + library, "pshinter" ); #endif /* create input stream from resource */ @@ -337,7 +439,7 @@ error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { - if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */ + if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ { FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); goto Bad_Format; @@ -365,8 +467,7 @@ pure_cff = 0; /* load font directory */ - error = sfnt->load_face( stream, face, - face_index, num_params, params ); + error = sfnt->load_face( stream, face, 0, num_params, params ); if ( error ) goto Exit; } @@ -408,13 +509,15 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( stream, face_index, cff ); + error = cff_font_load( library, stream, face_index, cff, pure_cff ); if ( error ) goto Exit; cff->pshinter = pshinter; cff->psnames = (void*)psnames; + cffface->face_index = face_index; + /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts; */ /* SFNT based fonts use the `name' table instead. */ @@ -427,13 +530,118 @@ /* which aren't CID-keyed */ if ( dict->cid_registry == 0xFFFFU && !psnames ) { - FT_ERROR(( "cff_face_init:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); + FT_ERROR(( "cff_face_init:" + " cannot open CFF & CEF fonts\n" + " " + " without the `PSNames' module\n" )); goto Bad_Format; } + if ( !dict->units_per_em ) + dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; + + /* Normalize the font matrix so that `matrix->xx' is 1; the */ + /* scaling is done with `units_per_em' then (at this point, */ + /* it already contains the scaling factor, but without */ + /* normalization of the matrix). */ + /* */ + /* Note that the offsets must be expressed in integer font */ + /* units. */ + + { + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_ULong* upm = &dict->units_per_em; + FT_Fixed temp = FT_ABS( matrix->yy ); + + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + + for ( i = cff->num_subfonts; i > 0; i-- ) + { + CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; + CFF_FontRecDict top = &cff->top_font.font_dict; + + FT_Matrix* matrix; + FT_Vector* offset; + FT_ULong* upm; + FT_Fixed temp; + + + if ( sub->units_per_em ) + { + FT_Long scaling; + + + if ( top->units_per_em > 1 && sub->units_per_em > 1 ) + scaling = FT_MIN( top->units_per_em, sub->units_per_em ); + else + scaling = 1; + + FT_Matrix_Multiply_Scaled( &top->font_matrix, + &sub->font_matrix, + scaling ); + FT_Vector_Transform_Scaled( &sub->font_offset, + &top->font_matrix, + scaling ); + + sub->units_per_em = FT_MulDiv( sub->units_per_em, + top->units_per_em, + scaling ); + } + else + { + sub->font_matrix = top->font_matrix; + sub->font_offset = top->font_offset; + + sub->units_per_em = top->units_per_em; + } + + matrix = &sub->font_matrix; + offset = &sub->font_offset; + upm = &sub->units_per_em; + temp = FT_ABS( matrix->yy ); + + if ( temp != 0x10000L ) + { + *upm = FT_DivFix( *upm, temp ); + + /* if *upm is larger than 100*1000 we divide by 1000 -- */ + /* this can happen if e.g. there is no top-font FontMatrix */ + /* and the subfont FontMatrix already contains the complete */ + /* scaling for the subfont (see section 5.11 of the PLRM) */ + + /* 100 is a heuristic value */ + + if ( *upm > 100L * 1000L ) + *upm = ( *upm + 500 ) / 1000; + + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + offset->x >>= 16; + offset->y >>= 16; + } + if ( pure_cff ) { char* style_name = NULL; @@ -444,20 +652,18 @@ /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) - cffface->num_glyphs = dict->cid_count; + cffface->num_glyphs = cff->charset.max_cid; else cffface->num_glyphs = cff->charstrings_index.count; /* set global bbox, as well as EM size */ - cffface->bbox.xMin = dict->font_bbox.xMin >> 16; - cffface->bbox.yMin = dict->font_bbox.yMin >> 16; - cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; - cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; + cffface->bbox.xMin = dict->font_bbox.xMin >> 16; + cffface->bbox.yMin = dict->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; + cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; - if ( !dict->units_per_em ) - dict->units_per_em = 1000; - - cffface->units_per_EM = dict->units_per_em; + cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); cffface->ascender = (FT_Short)( cffface->bbox.yMax ); cffface->descender = (FT_Short)( cffface->bbox.yMin ); @@ -561,22 +767,22 @@ /* */ /* Compute face flags. */ /* */ - flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ - FT_FACE_FLAG_HINTER; /* has native hinter */ + flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ + FT_FACE_FLAG_HINTER ); /* has native hinter */ if ( sfnt_format ) - flags |= FT_FACE_FLAG_SFNT; + flags |= (FT_UInt32)FT_FACE_FLAG_SFNT; /* fixed width font? */ if ( dict->is_fixed_pitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; + flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH; /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ #if 0 /* kerning available? */ if ( face->kern_pairs ) - flags |= FT_FACE_FLAG_KERNING; + flags |= (FT_UInt32)FT_FACE_FLAG_KERNING; #endif cffface->face_flags = flags; @@ -611,51 +817,25 @@ cffface->style_flags = flags; } - else - { - if ( !dict->units_per_em ) - dict->units_per_em = face->root.units_per_EM; - } - /* handle font matrix settings in subfonts (if any) */ - for ( i = cff->num_subfonts; i > 0; i-- ) - { - CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; - CFF_FontRecDict top = &cff->top_font.font_dict; - - - if ( sub->units_per_em ) - { - FT_Matrix scale; - - - scale.xx = scale.yy = (FT_Fixed)FT_DivFix( top->units_per_em, - sub->units_per_em ); - scale.xy = scale.yx = 0; - - FT_Matrix_Multiply( &scale, &sub->font_matrix ); - FT_Vector_Transform( &sub->font_offset, &scale ); - } - else - { - sub->font_matrix = top->font_matrix; - sub->font_offset = top->font_offset; - } - } #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ - /* has unset this flag because of the 3.0 `post' table */ + /* has unset this flag because of the 3.0 `post' table. */ if ( dict->cid_registry == 0xFFFFU ) cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif + if ( dict->cid_registry != 0xFFFFU && pure_cff ) + cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; + + /*******************************************************************/ /* */ /* Compute char maps. */ /* */ - /* Try to synthetize a Unicode charmap if there is none available */ + /* Try to synthesize a Unicode charmap if there is none available */ /* already. If an OpenType font contains a Unicode "cmap", we */ /* will use it, whatever be in the CFF part of the file. */ { @@ -683,7 +863,7 @@ if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) goto Exit; - /* we didn't find a Unicode charmap -- synthetize one */ + /* we didn't find a Unicode charmap -- synthesize one */ cmaprec.face = cffface; cmaprec.platform_id = 3; cmaprec.encoding_id = 1; @@ -691,7 +871,7 @@ nn = (FT_UInt)cffface->num_charmaps; - FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); + FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL ); /* if no Unicode charmap was previously selected, select this one */ if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) @@ -710,19 +890,19 @@ { cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } else if ( encoding->offset == 1 ) { cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } else { cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; - clazz = &cff_cmap_encoding_class_rec; + clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; } FT_CMap_New( clazz, NULL, &cmaprec, NULL ); @@ -742,11 +922,17 @@ FT_LOCAL_DEF( void ) cff_face_done( FT_Face cffface ) /* CFF_Face */ { - CFF_Face face = (CFF_Face)cffface; - FT_Memory memory = cffface->memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + CFF_Face face = (CFF_Face)cffface; + FT_Memory memory; + SFNT_Service sfnt; + if ( !face ) + return; + + memory = cffface->memory; + sfnt = (SFNT_Service)face->sfnt; + if ( sfnt ) sfnt->done_face( face ); diff --git a/lib/3rdparty/freetype/src/cff/cffobjs.h b/lib/3rdparty/freetype/src/cff/cffobjs.h index f18b5d9322d..3c81cee0094 100644 --- a/lib/3rdparty/freetype/src/cff/cffobjs.h +++ b/lib/3rdparty/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "cfftypes.h" #include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H FT_BEGIN_HEADER @@ -53,8 +54,8 @@ FT_BEGIN_HEADER /* */ typedef struct CFF_SizeRec_ { - FT_SizeRec root; - FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + FT_SizeRec root; + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ } CFF_SizeRec, *CFF_Size; @@ -80,6 +81,21 @@ FT_BEGIN_HEADER } CFF_GlyphSlotRec, *CFF_GlyphSlot; + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Internal */ + /* */ + /* <Description> */ + /* The interface to the `internal' field of `FT_Size'. */ + /* */ + typedef struct CFF_InternalRec_ + { + PSH_Globals topfont; + PSH_Globals subfonts[CFF_MAX_CID_FONTS]; + + } CFF_InternalRec, *CFF_Internal; + /*************************************************************************/ /* */ diff --git a/lib/3rdparty/freetype/src/cff/cffparse.c b/lib/3rdparty/freetype/src/cff/cffparse.c index 41af6a317f1..01266a193d2 100644 --- a/lib/3rdparty/freetype/src/cff/cffparse.c +++ b/lib/3rdparty/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,10 @@ #include <ft2build.h> #include "cffparse.h" #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H #include "cfferrs.h" +#include "cffpic.h" /*************************************************************************/ @@ -33,47 +35,20 @@ #define FT_COMPONENT trace_cffparse - enum - { - cff_kind_none = 0, - cff_kind_num, - cff_kind_fixed, - cff_kind_fixed_thousand, - cff_kind_string, - cff_kind_bool, - cff_kind_delta, - cff_kind_callback, - - cff_kind_max /* do not remove */ - }; - - - /* now generate handlers for the most simple fields */ - typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); - - typedef struct CFF_Field_Handler_ - { - int kind; - int code; - FT_UInt offset; - FT_Byte size; - CFF_Field_Reader reader; - FT_UInt array_max; - FT_UInt count_offset; - - } CFF_Field_Handler; FT_LOCAL_DEF( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, - void* object ) + void* object, + FT_Library library) { FT_MEM_ZERO( parser, sizeof ( *parser ) ); parser->top = parser->stack; parser->object_code = code; parser->object = object; + parser->library = library; } @@ -136,24 +111,53 @@ } + static const FT_Long power_tens[] = + { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L + }; + + /* read a real */ static FT_Fixed cff_parse_real( FT_Byte* start, FT_Byte* limit, - FT_Int power_ten ) + FT_Long power_ten, + FT_Long* scaling ) { - FT_Byte* p = start; - FT_Long num, divider, result, exponent; - FT_Int sign = 0, exponent_sign = 0; + FT_Byte* p = start; FT_UInt nib; FT_UInt phase; + FT_Long result, number, rest, exponent; + FT_Int sign = 0, exponent_sign = 0; + FT_Long exponent_add, integer_length, fraction_length; - result = 0; - num = 0; - divider = 1; - /* first of all, read the integer part */ + if ( scaling ) + *scaling = 0; + + result = 0; + + number = 0; + rest = 0; + exponent = 0; + + exponent_add = 0; + integer_length = 0; + fraction_length = 0; + + FT_UNUSED( rest ); + + /* First of all, read the integer part. */ phase = 4; for (;;) @@ -166,7 +170,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -178,10 +182,20 @@ else if ( nib > 9 ) break; else - result = result * 10 + nib; + { + /* Increase exponent if we can't add the digit. */ + if ( number >= 0xCCCCCCCL ) + exponent_add++; + /* Skip leading zeros. */ + else if ( nib || number ) + { + integer_length++; + number = number * 10 + nib; + } + } } - /* read decimal part, if any */ + /* Read fraction part, if any. */ if ( nib == 0xa ) for (;;) { @@ -193,7 +207,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -202,14 +216,18 @@ if ( nib >= 10 ) break; - if ( divider < 10000000L ) + /* Skip leading zeros if possible. */ + if ( !nib && !number ) + exponent_add--; + /* Only add digit if we don't overflow. */ + else if ( number < 0xCCCCCCCL && fraction_length < 9 ) { - num = num * 10 + nib; - divider *= 10; + fraction_length++; + number = number * 10 + nib; } } - /* read exponent, if any */ + /* Read exponent, if any. */ if ( nib == 12 ) { exponent_sign = 1; @@ -218,19 +236,17 @@ if ( nib == 11 ) { - exponent = 0; - for (;;) { - /* If we entered this iteration with phase == 4, we need */ - /* to read a new byte. */ + /* If we entered this iteration with phase == 4, */ + /* we need to read a new byte. */ if ( phase ) { p++; /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Bad; + goto Exit; } /* Get the nibble. */ @@ -240,47 +256,111 @@ break; exponent = exponent * 10 + nib; + + /* Arbitrarily limit exponent. */ + if ( exponent > 1000 ) + goto Exit; } if ( exponent_sign ) exponent = -exponent; - - power_ten += (FT_Int)exponent; } - /* raise to power of ten if needed */ - while ( power_ten > 0 ) + /* We don't check `power_ten' and `exponent_add'. */ + exponent += power_ten + exponent_add; + + if ( scaling ) { - result = result * 10; - num = num * 10; + /* Only use `fraction_length'. */ + fraction_length += integer_length; + exponent += integer_length; - power_ten--; + if ( fraction_length <= 5 ) + { + if ( number > 0x7FFFL ) + { + result = FT_DivFix( number, 10 ); + *scaling = exponent - fraction_length + 1; + } + else + { + if ( exponent > 0 ) + { + FT_Long new_fraction_length, shift; + + + /* Make `scaling' as small as possible. */ + new_fraction_length = FT_MIN( exponent, 5 ); + exponent -= new_fraction_length; + shift = new_fraction_length - fraction_length; + + number *= power_tens[shift]; + if ( number > 0x7FFFL ) + { + number /= 10; + exponent += 1; + } + } + else + exponent -= fraction_length; + + result = number << 16; + *scaling = exponent; + } + } + else + { + if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL ) + { + result = FT_DivFix( number, power_tens[fraction_length - 4] ); + *scaling = exponent - 4; + } + else + { + result = FT_DivFix( number, power_tens[fraction_length - 5] ); + *scaling = exponent - 5; + } + } } - - while ( power_ten < 0 ) + else { - result = result / 10; - divider = divider * 10; + integer_length += exponent; + fraction_length -= exponent; - power_ten++; + /* Check for overflow and underflow. */ + if ( FT_ABS( integer_length ) > 5 ) + goto Exit; + + /* Remove non-significant digits. */ + if ( integer_length < 0 ) { + number /= power_tens[-integer_length]; + fraction_length += integer_length; + } + + /* Convert into 16.16 format. */ + if ( fraction_length > 0 ) + { + if ( ( number / power_tens[fraction_length] ) > 0x7FFFL ) + goto Exit; + + result = FT_DivFix( number, power_tens[fraction_length] ); + } + else + { + number *= power_tens[-fraction_length]; + + if ( number > 0x7FFFL ) + goto Exit; + + result = number << 16; + } } - /* Move the integer part into the high 16 bits. */ - result <<= 16; - - /* Place the decimal part into the low 16 bits. */ - if ( num ) - result |= FT_DivFix( num, divider ); - if ( sign ) result = -result; Exit: return result; - - Bad: - result = 0; - goto Exit; } @@ -288,8 +368,8 @@ static FT_Long cff_parse_num( FT_Byte** d ) { - return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 ) - : cff_parse_integer( d[0], d[1] ) ); + return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) + : cff_parse_integer( d[0], d[1] ); } @@ -297,64 +377,120 @@ static FT_Fixed cff_parse_fixed( FT_Byte** d ) { - return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 ) - : cff_parse_integer( d[0], d[1] ) << 16 ); + return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL ) + : cff_parse_integer( d[0], d[1] ) << 16; } + /* read a floating point number, either integer or real, */ - /* but return 1000 times the number read in. */ + /* but return `10^scaling' times the number read in */ static FT_Fixed - cff_parse_fixed_thousand( FT_Byte** d ) + cff_parse_fixed_scaled( FT_Byte** d, + FT_Long scaling ) { - return **d == - 30 ? cff_parse_real ( d[0], d[1], 3 ) - : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 ); + return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL ) + : ( cff_parse_integer( d[0], d[1] ) * + power_tens[scaling] ) << 16; } + + /* read a floating point number, either integer or real, */ + /* and return it as precise as possible -- `scaling' returns */ + /* the scaling factor (as a power of 10) */ + static FT_Fixed + cff_parse_fixed_dynamic( FT_Byte** d, + FT_Long* scaling ) + { + FT_ASSERT( scaling ); + + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], 0, scaling ); + else + { + FT_Long number; + FT_Int integer_length; + + + number = cff_parse_integer( d[0], d[1] ); + + if ( number > 0x7FFFL ) + { + for ( integer_length = 5; integer_length < 10; integer_length++ ) + if ( number < power_tens[integer_length] ) + break; + + if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL ) + { + *scaling = integer_length - 4; + return FT_DivFix( number, power_tens[integer_length - 4] ); + } + else + { + *scaling = integer_length - 5; + return FT_DivFix( number, power_tens[integer_length - 5] ); + } + } + else + { + *scaling = 0; + return number << 16; + } + } + } + + static FT_Error cff_parse_font_matrix( CFF_Parser parser ) { CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; - FT_UShort* upm = &dict->units_per_em; + FT_ULong* upm = &dict->units_per_em; FT_Byte** data = parser->stack; - FT_Error error; - FT_Fixed temp; + FT_Error error = CFF_Err_Stack_Underflow; - error = CFF_Err_Stack_Underflow; - if ( parser->top >= parser->stack + 6 ) { - matrix->xx = cff_parse_fixed_thousand( data++ ); - matrix->yx = cff_parse_fixed_thousand( data++ ); - matrix->xy = cff_parse_fixed_thousand( data++ ); - matrix->yy = cff_parse_fixed_thousand( data++ ); - offset->x = cff_parse_fixed_thousand( data++ ); - offset->y = cff_parse_fixed_thousand( data ); + FT_Long scaling; - temp = FT_ABS( matrix->yy ); - - *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); - - if ( temp != 0x10000L ) - { - matrix->xx = FT_DivFix( matrix->xx, temp ); - matrix->yx = FT_DivFix( matrix->yx, temp ); - matrix->xy = FT_DivFix( matrix->xy, temp ); - matrix->yy = FT_DivFix( matrix->yy, temp ); - offset->x = FT_DivFix( offset->x, temp ); - offset->y = FT_DivFix( offset->y, temp ); - } - - /* note that the offsets must be expressed in integer font units */ - offset->x >>= 16; - offset->y >>= 16; error = CFF_Err_Ok; + + /* We expect a well-formed font matrix, this is, the matrix elements */ + /* `xx' and `yy' are of approximately the same magnitude. To avoid */ + /* loss of precision, we use the magnitude of element `xx' to scale */ + /* all other elements. The scaling factor is then contained in the */ + /* `units_per_em' value. */ + + matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + + scaling = -scaling; + + if ( scaling < 0 || scaling > 9 ) + { + /* Return default matrix in case of unlikely values. */ + matrix->xx = 0x10000L; + matrix->yx = 0; + matrix->yx = 0; + matrix->yy = 0x10000L; + offset->x = 0; + offset->y = 0; + *upm = 1; + + goto Exit; + } + + matrix->yx = cff_parse_fixed_scaled( data++, scaling ); + matrix->xy = cff_parse_fixed_scaled( data++, scaling ); + matrix->yy = cff_parse_fixed_scaled( data++, scaling ); + offset->x = cff_parse_fixed_scaled( data++, scaling ); + offset->y = cff_parse_fixed_scaled( data, scaling ); + + *upm = power_tens[scaling]; } + Exit: return error; } @@ -418,7 +554,12 @@ { dict->cid_registry = (FT_UInt)cff_parse_num ( data++ ); dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ ); - dict->cid_supplement = (FT_ULong)cff_parse_num( data ); + if ( **data == 30 ) + FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); + dict->cid_supplement = cff_parse_num( data ); + if ( dict->cid_supplement < 0 ) + FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", + dict->cid_supplement )); error = CFF_Err_Ok; } @@ -439,6 +580,11 @@ #define CFF_FIELD_DELTA( code, name, max ) \ CFF_FIELD( code, name, cff_kind_delta ) +#define CFFCODE_TOPDICT 0x1000 +#define CFFCODE_PRIVATE 0x2000 + +#ifndef FT_CONFIG_OPTION_PIC + #define CFF_FIELD_CALLBACK( code, name ) \ { \ cff_kind_callback, \ @@ -470,9 +616,6 @@ FT_FIELD_OFFSET( num_ ## name ) \ }, -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - static const CFF_Field_Handler cff_field_handlers[] = { @@ -482,13 +625,99 @@ }; +#else /* FT_CONFIG_OPTION_PIC */ + + void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class) + { + CFF_Field_Handler* clazz; + FT_Error error; + FT_Memory memory = library->memory; + int i=0; + +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK +#define CFF_FIELD_CALLBACK( code, name ) i++; +#define CFF_FIELD( code, name, kind ) i++; +#define CFF_FIELD_DELTA( code, name, max ) i++; + +#include "cfftoken.h" + i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/ + + if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) ) + return error; + + i=0; +#undef CFF_FIELD +#undef CFF_FIELD_DELTA +#undef CFF_FIELD_CALLBACK + +#define CFF_FIELD_CALLBACK( code_, name_ ) \ + clazz[i].kind = cff_kind_callback; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_ ## name_; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; + +#undef CFF_FIELD +#define CFF_FIELD( code_, name_, kind_ ) \ + clazz[i].kind = kind_; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; \ + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code_, name_, max_ ) \ + clazz[i].kind = cff_kind_delta; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = FT_FIELD_OFFSET( name_ ); \ + clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \ + clazz[i].reader = 0; \ + clazz[i].array_max = max_; \ + clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ + i++; + +#include "cfftoken.h" + + clazz[i].kind = 0; + clazz[i].code = 0; + clazz[i].offset = 0; + clazz[i].size = 0; + clazz[i].reader = 0; + clazz[i].array_max = 0; + clazz[i].count_offset = 0; + + *output_class = clazz; + return FT_Err_Ok; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + FT_LOCAL_DEF( FT_Error ) cff_parser_run( CFF_Parser parser, FT_Byte* start, FT_Byte* limit ) { - FT_Byte* p = start; - FT_Error error = CFF_Err_Ok; + FT_Byte* p = start; + FT_Error error = CFF_Err_Ok; + FT_Library library = parser->library; + FT_UNUSED(library); parser->top = parser->stack; @@ -516,8 +745,10 @@ p++; for (;;) { + /* An unterminated floating point number at the */ + /* end of a dictionary is invalid but harmless. */ if ( p >= limit ) - goto Syntax_Error; + goto Exit; v = p[0] >> 4; if ( v == 15 ) break; @@ -558,7 +789,7 @@ } code = code | parser->object_code; - for ( field = cff_field_handlers; field->kind; field++ ) + for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ ) { if ( field->code == (FT_Int)code ) { @@ -585,7 +816,7 @@ goto Store_Number; case cff_kind_fixed_thousand: - val = cff_parse_fixed_thousand( parser->stack ); + val = cff_parse_fixed_scaled( parser->stack, 3 ); Store_Number: switch ( field->size ) diff --git a/lib/3rdparty/freetype/src/cff/cffparse.h b/lib/3rdparty/freetype/src/cff/cffparse.h index 8f3fa588592..7e2c00a0449 100644 --- a/lib/3rdparty/freetype/src/cff/cffparse.h +++ b/lib/3rdparty/freetype/src/cff/cffparse.h @@ -36,6 +36,7 @@ FT_BEGIN_HEADER typedef struct CFF_ParserRec_ { + FT_Library library; FT_Byte* start; FT_Byte* limit; FT_Byte* cursor; @@ -52,7 +53,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, - void* object ); + void* object, + FT_Library library); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -60,6 +62,37 @@ FT_BEGIN_HEADER FT_Byte* limit ); + enum + { + cff_kind_none = 0, + cff_kind_num, + cff_kind_fixed, + cff_kind_fixed_thousand, + cff_kind_string, + cff_kind_bool, + cff_kind_delta, + cff_kind_callback, + + cff_kind_max /* do not remove */ + }; + + + /* now generate handlers for the most simple fields */ + typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); + + typedef struct CFF_Field_Handler_ + { + int kind; + int code; + FT_UInt offset; + FT_Byte size; + CFF_Field_Reader reader; + FT_UInt array_max; + FT_UInt count_offset; + + } CFF_Field_Handler; + + FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/cff/cffpic.c b/lib/3rdparty/freetype/src/cff/cffpic.c new file mode 100644 index 00000000000..568956d6a93 --- /dev/null +++ b/lib/3rdparty/freetype/src/cff/cffpic.c @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* cffpic.c */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "cffpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from cffdrivr.c */ + FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*); + void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*); + + /* forward declaration of PIC init functions from cffparse.c */ + FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**); + void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*); + + /* forward declaration of PIC init functions from cffcmap.c */ + void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*); + void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*); + + void + cff_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->cff ) + { + CffModulePIC* container = (CffModulePIC*)pic_container->cff; + if(container->cff_services) + FT_Destroy_Class_cff_services(library, container->cff_services); + container->cff_services = NULL; + if(container->cff_field_handlers) + FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers); + container->cff_field_handlers = NULL; + FT_FREE( container ); + pic_container->cff = NULL; + } + } + + FT_Error + cff_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + CffModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->cff = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_cff_services(library, &container->cff_services); + if(error) + goto Exit; + error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers); + if(error) + goto Exit; + FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info); + FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict); + FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name); + FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info); + FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info); + FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec); + FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec); +Exit: + if(error) + cff_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/cff/cffpic.h b/lib/3rdparty/freetype/src/cff/cffpic.h new file mode 100644 index 00000000000..e29d068134b --- /dev/null +++ b/lib/3rdparty/freetype/src/cff/cffpic.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* cffpic.h */ +/* */ +/* The FreeType position independent code services for cff module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __CFFPIC_H__ +#define __CFFPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_CFF_SERVICE_PS_INFO_GET cff_service_ps_info +#define FT_CFF_SERVICE_GLYPH_DICT_GET cff_service_glyph_dict +#define FT_CFF_SERVICE_PS_NAME_GET cff_service_ps_name +#define FT_CFF_SERVICE_GET_CMAP_INFO_GET cff_service_get_cmap_info +#define FT_CFF_SERVICE_CID_INFO_GET cff_service_cid_info +#define FT_CFF_SERVICES_GET cff_services +#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec +#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec +#define FT_CFF_FIELD_HANDLERS_GET cff_field_handlers + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_GLYPH_DICT_H +#include "cffparse.h" +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_CID_H + + typedef struct CffModulePIC_ + { + FT_ServiceDescRec* cff_services; + CFF_Field_Handler* cff_field_handlers; + FT_Service_PsInfoRec cff_service_ps_info; + FT_Service_GlyphDictRec cff_service_glyph_dict; + FT_Service_PsFontNameRec cff_service_ps_name; + FT_Service_TTCMapsRec cff_service_get_cmap_info; + FT_Service_CIDRec cff_service_cid_info; + FT_CMap_ClassRec cff_cmap_encoding_class_rec; + FT_CMap_ClassRec cff_cmap_unicode_class_rec; + } CffModulePIC; + +#define GET_PIC(lib) ((CffModulePIC*)((lib)->pic_container.cff)) +#define FT_CFF_SERVICE_PS_INFO_GET (GET_PIC(library)->cff_service_ps_info) +#define FT_CFF_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->cff_service_glyph_dict) +#define FT_CFF_SERVICE_PS_NAME_GET (GET_PIC(library)->cff_service_ps_name) +#define FT_CFF_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->cff_service_get_cmap_info) +#define FT_CFF_SERVICE_CID_INFO_GET (GET_PIC(library)->cff_service_cid_info) +#define FT_CFF_SERVICES_GET (GET_PIC(library)->cff_services) +#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec) +#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET (GET_PIC(library)->cff_cmap_unicode_class_rec) +#define FT_CFF_FIELD_HANDLERS_GET (GET_PIC(library)->cff_field_handlers) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __CFFPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/cff/cfftypes.h b/lib/3rdparty/freetype/src/cff/cfftypes.h index 306e5aab670..df92e9a1ac3 100644 --- a/lib/3rdparty/freetype/src/cff/cfftypes.h +++ b/lib/3rdparty/freetype/src/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -114,7 +114,7 @@ FT_BEGIN_HEADER FT_Int paint_type; FT_Int charstring_type; FT_Matrix font_matrix; - FT_UShort units_per_em; + FT_ULong units_per_em; /* temporarily used as scaling value also */ FT_Vector font_offset; FT_ULong unique_id; FT_BBox font_bbox; @@ -130,7 +130,7 @@ FT_BEGIN_HEADER /* these should only be used for the top-level font dictionary */ FT_UInt cid_registry; FT_UInt cid_ordering; - FT_ULong cid_supplement; + FT_Long cid_supplement; FT_Long cid_font_version; FT_Long cid_font_revision; @@ -259,6 +259,10 @@ FT_BEGIN_HEADER /* since version 2.3.0 */ PS_FontInfoRec* font_info; /* font info dictionary */ + /* since version 2.3.6 */ + FT_String* registry; + FT_String* ordering; + } CFF_FontRec, *CFF_Font; diff --git a/lib/3rdparty/freetype/src/cff/module.mk b/lib/3rdparty/freetype/src/cff/module.mk index 0474e37b69c..ef1391c279b 100644 --- a/lib/3rdparty/freetype/src/cff/module.mk +++ b/lib/3rdparty/freetype/src/cff/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += CFF_DRIVER define CFF_DRIVER -$(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, cff_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/cid/cidgload.c b/lib/3rdparty/freetype/src/cid/cidgload.c index 8bec6e187b4..ea61b4e1283 100644 --- a/lib/3rdparty/freetype/src/cid/cidgload.c +++ b/lib/3rdparty/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H #include "ciderrs.h" @@ -51,20 +52,25 @@ FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + + + FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index )); #ifdef FT_CONFIG_OPTION_INCREMENTAL /* For incremental fonts get the character data using */ /* the callback function. */ - if ( face->root.internal->incremental_interface ) + if ( inc ) { FT_Data glyph_data; - error = face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, - &glyph_data ); + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, &glyph_data ); if ( error ) goto Exit; @@ -74,15 +80,13 @@ if ( glyph_data.length != 0 ) { glyph_length = glyph_data.length - cid->fd_bytes; - FT_ALLOC( charstring, glyph_length ); + (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, glyph_length ); } - face->root.internal->incremental_interface->funcs->free_glyph_data( - face->root.internal->incremental_interface->object, - &glyph_data ); + inc->funcs->free_glyph_data( inc->object, &glyph_data ); if ( error ) goto Exit; @@ -163,23 +167,22 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + if ( !error && inc && inc->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; - metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - decoder->builder.left_bearing.x = metrics.bearing_x; - decoder->builder.left_bearing.y = metrics.bearing_y; - decoder->builder.advance.x = metrics.advance; - decoder->builder.advance.y = 0; + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = 0; + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); + decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -251,7 +254,7 @@ /* ignore the error if one occurred - skip to next glyph */ } - *max_advance = decoder.builder.advance.x; + *max_advance = FIXED_TO_INT( decoder.builder.advance.x ); psaux->t1_decoder_funcs->done( &decoder ); @@ -342,8 +345,10 @@ FT_Slot_Internal internal = cidglyph->internal; - cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x; - cidglyph->metrics.horiAdvance = decoder.builder.advance.x; + cidglyph->metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + cidglyph->metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); internal->glyph_matrix = font_matrix; internal->glyph_delta = font_offset; @@ -357,8 +362,10 @@ /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - cidglyph->linearHoriAdvance = decoder.builder.advance.x; + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + cidglyph->linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); cidglyph->internal->glyph_transformed = 0; /* make up vertical ones */ @@ -420,9 +427,12 @@ metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } Exit: diff --git a/lib/3rdparty/freetype/src/cid/cidload.c b/lib/3rdparty/freetype/src/cid/cidload.c index 9ed8cee46c7..3bb359446f9 100644 --- a/lib/3rdparty/freetype/src/cid/cidload.c +++ b/lib/3rdparty/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -97,6 +97,10 @@ object = (FT_Byte*)&cid->font_info; break; + case T1_FIELD_LOCATION_FONT_EXTRA: + object = (FT_Byte*)&face->font_extra; + break; + case T1_FIELD_LOCATION_BBOX: object = (FT_Byte*)&cid->font_bbox; break; @@ -108,7 +112,7 @@ if ( parser->num_dict < 0 ) { - FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n", + FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", keyword->ident )); error = CID_Err_Syntax_Error; goto Exit; @@ -234,14 +238,38 @@ } + /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ + /* and CID_FaceDictRec (both are public header files and can't */ + /* changed); we simply copy the value */ + + FT_CALLBACK_DEF( FT_Error ) + parse_expansion_factor( CID_Face face, + CID_Parser* parser ) + { + CID_FaceDict dict; + + + if ( parser->num_dict >= 0 ) + { + dict = face->cid.font_dicts + parser->num_dict; + + dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); + dict->private_dict.expansion_factor = dict->expansion_factor; + } + + return CID_Err_Ok; + } + + static const T1_FieldRec cid_field_records[] = { #include "cidtoken.h" - T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) - T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 ) + T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } }; diff --git a/lib/3rdparty/freetype/src/cid/cidobjs.c b/lib/3rdparty/freetype/src/cid/cidobjs.c index 1b3bfbf749a..82678af0d4b 100644 --- a/lib/3rdparty/freetype/src/cid/cidobjs.c +++ b/lib/3rdparty/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -193,61 +193,61 @@ FT_LOCAL_DEF( void ) cid_face_done( FT_Face cidface ) /* CID_Face */ { - CID_Face face = (CID_Face)cidface; - FT_Memory memory; + CID_Face face = (CID_Face)cidface; + FT_Memory memory; + CID_FaceInfo cid; + PS_FontInfo info; - if ( face ) + if ( !face ) + return; + + cid = &face->cid; + info = &cid->font_info; + memory = cidface->memory; + + /* release subrs */ + if ( face->subrs ) { - CID_FaceInfo cid = &face->cid; - PS_FontInfo info = &cid->font_info; + FT_Int n; - memory = cidface->memory; - - /* release subrs */ - if ( face->subrs ) + for ( n = 0; n < cid->num_dicts; n++ ) { - FT_Int n; + CID_Subrs subr = face->subrs + n; - for ( n = 0; n < cid->num_dicts; n++ ) + if ( subr->code ) { - CID_Subrs subr = face->subrs + n; - - - if ( subr->code ) - { - FT_FREE( subr->code[0] ); - FT_FREE( subr->code ); - } + FT_FREE( subr->code[0] ); + FT_FREE( subr->code ); } - - FT_FREE( face->subrs ); } - /* release FontInfo strings */ - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - - /* release font dictionaries */ - FT_FREE( cid->font_dicts ); - cid->num_dicts = 0; - - /* release other strings */ - FT_FREE( cid->cid_font_name ); - FT_FREE( cid->registry ); - FT_FREE( cid->ordering ); - - cidface->family_name = 0; - cidface->style_name = 0; - - FT_FREE( face->binary_data ); - FT_FREE( face->cid_stream ); + FT_FREE( face->subrs ); } + + /* release FontInfo strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release font dictionaries */ + FT_FREE( cid->font_dicts ); + cid->num_dicts = 0; + + /* release other strings */ + FT_FREE( cid->cid_font_name ); + FT_FREE( cid->registry ); + FT_FREE( cid->ordering ); + + cidface->family_name = 0; + cidface->style_name = 0; + + FT_FREE( face->binary_data ); + FT_FREE( face->cid_stream ); } @@ -324,6 +324,7 @@ goto Exit; /* check the face index */ + /* XXX: handle CID fonts with more than a single face */ if ( face_index != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); @@ -412,10 +413,11 @@ cidface->num_fixed_sizes = 0; cidface->available_sizes = 0; - cidface->bbox.xMin = cid->font_bbox.xMin >> 16; - cidface->bbox.yMin = cid->font_bbox.yMin >> 16; - cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFFU ) >> 16; - cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFFU ) >> 16; + cidface->bbox.xMin = cid->font_bbox.xMin >> 16; + cidface->bbox.yMin = cid->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16; + cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16; if ( !cidface->units_per_EM ) cidface->units_per_EM = 1000; diff --git a/lib/3rdparty/freetype/src/cid/cidparse.c b/lib/3rdparty/freetype/src/cid/cidparse.c index bb87afc5891..efed618f5af 100644 --- a/lib/3rdparty/freetype/src/cid/cidparse.c +++ b/lib/3rdparty/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,6 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H @@ -87,13 +86,13 @@ /* `StartData' or `/sfnts' */ { FT_Byte buffer[256 + 10]; - FT_Int read_len = 256 + 10; + FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ FT_Byte* p = buffer; - for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 ) + for ( offset = FT_STREAM_POS(); ; offset += 256 ) { - FT_Int stream_len; + FT_Long stream_len; /* same as signed FT_Stream->size */ stream_len = stream->size - FT_STREAM_POS(); diff --git a/lib/3rdparty/freetype/src/cid/cidriver.c b/lib/3rdparty/freetype/src/cid/cidriver.c index 5c5a72957c0..3a2d22532a6 100644 --- a/lib/3rdparty/freetype/src/cid/cidriver.c +++ b/lib/3rdparty/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,13 +20,14 @@ #include "cidriver.h" #include "cidgload.h" #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H #include "ciderrs.h" #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_CID_H + /*************************************************************************/ /* */ @@ -38,10 +39,10 @@ #define FT_COMPONENT trace_ciddriver - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* cid_get_postscript_name( CID_Face face ) @@ -62,38 +63,114 @@ }; - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error cid_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((CID_Face)face)->cid.font_info; - return 0; + + return CID_Err_Ok; } + static FT_Error + cid_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((CID_Face)face)->font_extra; + + return CID_Err_Ok; + } static const FT_Service_PsInfoRec cid_service_ps_info = { (PS_GetFontInfoFunc) cid_ps_get_font_info, + (PS_GetFontExtraFunc) cid_ps_get_font_extra, (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ (PS_GetFontPrivateFunc)NULL /* unsupported */ }; - /* - * SERVICE LIST - * - */ + /* + * CID INFO SERVICE + * + */ + static FT_Error + cid_get_ros( CID_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ) + { + CID_FaceInfo cid = &face->cid; + + + if ( registry ) + *registry = cid->registry; + + if ( ordering ) + *ordering = cid->ordering; + + if ( supplement ) + *supplement = cid->supplement; + + return CID_Err_Ok; + } + + + static FT_Error + cid_get_is_cid( CID_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CID_Err_Ok; + FT_UNUSED( face ); + + + if ( is_cid ) + *is_cid = 1; /* cid driver is only used for CID keyed fonts */ + + return error; + } + + + static FT_Error + cid_get_cid_from_glyph_index( CID_Face face, + FT_UInt glyph_index, + FT_UInt *cid ) + { + FT_Error error = CID_Err_Ok; + FT_UNUSED( face ); + + + if ( cid ) + *cid = glyph_index; /* identity mapping */ + + return error; + } + + + static const FT_Service_CIDRec cid_service_cid_info = + { + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + }; + + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec cid_services[] = { - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { FT_SERVICE_ID_CID, &cid_service_cid_info }, { NULL, NULL } }; diff --git a/lib/3rdparty/freetype/src/cid/cidriver.h b/lib/3rdparty/freetype/src/cid/cidriver.h index d5a80f6f9fb..c7f424bb389 100644 --- a/lib/3rdparty/freetype/src/cid/cidriver.h +++ b/lib/3rdparty/freetype/src/cid/cidriver.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_CALLBACK_TABLE const FT_Driver_ClassRec t1cid_driver_class; diff --git a/lib/3rdparty/freetype/src/cid/cidtoken.h b/lib/3rdparty/freetype/src/cid/cidtoken.h index ad5bbb2eefd..904cb09cf4d 100644 --- a/lib/3rdparty/freetype/src/cid/cidtoken.h +++ b/lib/3rdparty/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,7 @@ #define T1CODE T1_FIELD_LOCATION_CID_INFO T1_FIELD_KEY ( "CIDFontName", cid_font_name, 0 ) - T1_FIELD_NUM ( "CIDFontVersion", cid_version, 0 ) + T1_FIELD_FIXED ( "CIDFontVersion", cid_version, 0 ) T1_FIELD_NUM ( "CIDFontType", cid_font_type, 0 ) T1_FIELD_STRING( "Registry", registry, 0 ) T1_FIELD_STRING( "Ordering", ordering, 0 ) @@ -49,6 +49,13 @@ T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + #undef FT_STRUCTURE #define FT_STRUCTURE CID_FaceDictRec @@ -62,7 +69,6 @@ T1_FIELD_NUM ( "SubrCount", num_subrs, 0 ) T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar, 0 ) T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 ) - T1_FIELD_FIXED( "ExpansionFactor", expansion_factor, 0 ) T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 ) @@ -92,6 +98,9 @@ T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 ) T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 ) + T1_FIELD_BOOL ( "ForceBold", force_bold, 0 ) + + #undef FT_STRUCTURE #define FT_STRUCTURE FT_BBox #undef T1CODE diff --git a/lib/3rdparty/freetype/src/cid/module.mk b/lib/3rdparty/freetype/src/cid/module.mk index 41e5a68e599..ce30bfd7ae4 100644 --- a/lib/3rdparty/freetype/src/cid/module.mk +++ b/lib/3rdparty/freetype/src/cid/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TYPE1CID_DRIVER define TYPE1CID_DRIVER -$(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, t1cid_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c b/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c index 6cca65831e0..3d100315636 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvbsln.c @@ -71,10 +71,10 @@ static void gxv_bsln_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { - FT_UShort v = value.u; + FT_UShort v = value_p->u; FT_UShort* ctlPoints; FT_UNUSED( glyph ); @@ -122,7 +122,7 @@ static GXV_LookupValueDesc gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -132,7 +132,7 @@ GXV_LookupValueDesc value; /* XXX: check range ? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + ( relative_gindex * sizeof ( FT_UShort ) ) ); p = valid->lookuptbl_head + offset; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c b/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c index 82fd6b3a6d3..de7ce6fdef1 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvcommn.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT common tables validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004, 2005, 2009 */ +/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,11 +51,11 @@ FT_UShort* b ) { if ( *a < *b ) - return ( -1 ); + return -1; else if ( *a > *b ) - return ( 1 ); + return 1; else - return ( 0 ); + return 0; } @@ -115,11 +116,11 @@ FT_ULong* b ) { if ( *a < *b ) - return ( -1 ); + return -1; else if ( *a > *b ) - return ( 1 ); + return 1; else - return ( 0 ); + return 0; } @@ -404,8 +405,8 @@ if ( UNITSIZE != CORRECTSIZE ) \ { \ FT_ERROR(( "unitSize=%d differs from" \ - "expected unitSize=%d" \ - "in LookupTable %s", \ + " expected unitSize=%d" \ + " in LookupTable %s\n", \ UNITSIZE, CORRECTSIZE, FORMAT )); \ if ( UNITSIZE != 0 && NUNITS != 0 ) \ { \ @@ -447,7 +448,7 @@ } value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( i, value, valid ); + valid->lookupval_func( i, &value, valid ); } valid->subtable_length = p - table; @@ -552,7 +553,7 @@ } for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) - valid->lookupval_func( gid, value, valid ); + valid->lookupval_func( gid, &value, valid ); } gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); @@ -630,11 +631,11 @@ for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) { value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), - base_value, + &base_value, limit, valid ); - valid->lookupval_func( gid, value, valid ); + valid->lookupval_func( gid, &value, valid ); } } @@ -709,7 +710,7 @@ } prev_glyph = glyph; - valid->lookupval_func( glyph, value, valid ); + valid->lookupval_func( glyph, &value, valid ); } gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); @@ -749,7 +750,7 @@ { GXV_LIMIT_CHECK( 2 ); value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); - valid->lookupval_func( (FT_UShort)( firstGlyph + i ), value, valid ); + valid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, valid ); } valid->subtable_length = p - table; @@ -1180,7 +1181,7 @@ if ( NULL != valid->statetable.entry_validate_func ) valid->statetable.entry_validate_func( state, flags, - glyphOffset, + &glyphOffset, statetable_table, statetable_limit, valid ); @@ -1351,15 +1352,15 @@ static void gxv_XClassTable_lookupval_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - if ( value.u >= valid->xstatetable.nClasses ) + if ( value_p->u >= valid->xstatetable.nClasses ) FT_INVALID_DATA; - if ( value.u > valid->xstatetable.maxClassID ) - valid->xstatetable.maxClassID = value.u; + if ( value_p->u > valid->xstatetable.maxClassID ) + valid->xstatetable.maxClassID = value_p->u; } @@ -1391,7 +1392,7 @@ */ static GXV_LookupValueDesc gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -1401,7 +1402,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->lookuptbl_head + offset; @@ -1555,7 +1556,7 @@ if ( NULL != valid->xstatetable.entry_validate_func ) valid->xstatetable.entry_validate_func( state, flags, - glyphOffset, + &glyphOffset, xstatetable_table, xstatetable_limit, valid ); diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h b/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h index 0128eca79e3..404c07ffad9 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h +++ b/lib/3rdparty/freetype/src/gxvalid/gxvcommn.h @@ -79,6 +79,8 @@ FT_BEGIN_HEADER } GXV_LookupValueDesc; + typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr; + typedef enum GXV_LookupValue_SignSpec_ { GXV_LOOKUPVALUE_UNSIGNED = 0, @@ -89,12 +91,12 @@ FT_BEGIN_HEADER typedef void (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ); typedef GXV_LookupValueDesc (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ); @@ -134,6 +136,7 @@ FT_BEGIN_HEADER } GXV_StateTable_GlyphOffsetDesc; + typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr; typedef void (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort table_size, @@ -149,7 +152,7 @@ FT_BEGIN_HEADER (*GXV_StateTable_Entry_Validate_Func)( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes statetable_table, FT_Bytes statetable_limit, GXV_Validator valid ); @@ -175,6 +178,8 @@ FT_BEGIN_HEADER typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc; + typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr; + typedef void (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong table_size, FT_ULong classTable, @@ -189,7 +194,7 @@ FT_BEGIN_HEADER (*GXV_XStateTable_Entry_Validate_Func)( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, GXV_Validator valid ); @@ -275,11 +280,11 @@ FT_BEGIN_HEADER #else /* !FT_DEBUG_LEVEL_TRACE */ -#define GXV_INIT do ; while ( 0 ) -#define GXV_NAME_ENTER( name ) do ; while ( 0 ) -#define GXV_EXIT do ; while ( 0 ) +#define GXV_INIT do { } while ( 0 ) +#define GXV_NAME_ENTER( name ) do { } while ( 0 ) +#define GXV_EXIT do { } while ( 0 ) -#define GXV_TRACE( s ) do ; while ( 0 ) +#define GXV_TRACE( s ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_TRACE */ diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c b/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c index d7c6ad166d5..002fec6d6b1 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvfeat.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT feat table validation (body). */ /* */ -/* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2004, 2005, 2008 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,7 +60,7 @@ #define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field ) - typedef enum + typedef enum GXV_FeatureFlagsMask_ { GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U, GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, @@ -198,7 +199,7 @@ FT_UShort feature; FT_UShort nSettings; - FT_UInt settingTable; + FT_ULong settingTable; FT_UShort featureFlags; FT_Bool exclusive; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvjust.c b/lib/3rdparty/freetype/src/gxvalid/gxvjust.c index 29bf840b57a..e14f946f2da 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvjust.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvjust.c @@ -323,15 +323,15 @@ static void gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - if ( value.u > GXV_JUST_DATA( pc_offset_max ) ) - GXV_JUST_DATA( pc_offset_max ) = value.u; - if ( value.u < GXV_JUST_DATA( pc_offset_max ) ) - GXV_JUST_DATA( pc_offset_min ) = value.u; + if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) ) + GXV_JUST_DATA( pc_offset_max ) = value_p->u; + if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) ) + GXV_JUST_DATA( pc_offset_min ) = value_p->u; } @@ -384,7 +384,7 @@ gxv_just_classTable_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -395,7 +395,7 @@ FT_UShort currentClass; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); FT_UNUSED( table ); FT_UNUSED( limit ); FT_UNUSED( valid ); @@ -449,15 +449,15 @@ static void gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - if ( value.u > GXV_JUST_DATA( wdc_offset_max ) ) - GXV_JUST_DATA( wdc_offset_max ) = value.u; - if ( value.u < GXV_JUST_DATA( wdc_offset_min ) ) - GXV_JUST_DATA( wdc_offset_min ) = value.u; + if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) ) + GXV_JUST_DATA( wdc_offset_max ) = value_p->u; + if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) ) + GXV_JUST_DATA( wdc_offset_min ) = value_p->u; } @@ -557,7 +557,7 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - FT_UInt table_size; + FT_Offset table_size; GXV_ValidatorRec validrec; GXV_Validator valid = &validrec; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvkern.c b/lib/3rdparty/freetype/src/gxvalid/gxvkern.c index bfb405f65ba..2137db842a4 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvkern.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvkern.c @@ -256,7 +256,7 @@ gxv_kern_subtable_fmt1_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -268,7 +268,7 @@ FT_UShort kernValue; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); push = (FT_UShort)( ( flags >> 15 ) & 1 ); diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c b/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c index 48821ea8796..f14fa5b1313 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvlcar.c @@ -83,10 +83,10 @@ static void gxv_lcar_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { - FT_Bytes p = valid->root->base + value.u; + FT_Bytes p = valid->root->base + value_p->u; FT_Bytes limit = valid->root->limit; FT_UShort count; FT_Short partial; @@ -146,7 +146,7 @@ static GXV_LookupValueDesc gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -158,7 +158,7 @@ FT_UNUSED( lookuptbl_limit ); /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->root->base + offset; limit = valid->root->limit; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmod.h b/lib/3rdparty/freetype/src/gxvalid/gxvmod.h index 466584ef4fd..d912a8f8381 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmod.h +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmod.h @@ -34,6 +34,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) gxv_module_class; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort.c b/lib/3rdparty/freetype/src/gxvalid/gxvmort.c index 6fb71b92be4..0aa066339df 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort.c @@ -42,7 +42,7 @@ gxv_mort_feature_validate( GXV_mort_feature f, GXV_Validator valid ) { - if ( f->featureType > gxv_feat_registry_length ) + if ( f->featureType >= gxv_feat_registry_length ) { GXV_TRACE(( "featureType %d is out of registered range, " "setting %d is unchecked\n", @@ -85,17 +85,17 @@ /* - * nFeatureFlags is typed to FT_UInt to accept that in + * nFeatureFlags is typed to FT_ULong to accept that in * mort (typed FT_UShort) and morx (typed FT_ULong). */ FT_LOCAL_DEF( void ) gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, - FT_UInt nFeatureFlags, + FT_ULong nFeatureFlags, GXV_Validator valid ) { FT_Bytes p = table; - FT_UInt i; + FT_ULong i; GXV_mort_featureRec f = GXV_MORT_FEATURE_OFF; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort.h b/lib/3rdparty/freetype/src/gxvalid/gxvmort.h index 1d64e69c475..1e5a1f5ab68 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort.h +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort.h @@ -54,7 +54,7 @@ FT_LOCAL( void ) gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, - FT_UInt nFeatureFlags, + FT_ULong nFeatureFlags, GXV_Validator valid ); FT_LOCAL( void ) diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c b/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c index 0902056c628..0453062f636 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort0.c @@ -64,7 +64,7 @@ gxv_mort_subtable_type0_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -80,7 +80,7 @@ FT_UNUSED( limit ); FT_UNUSED( GXV_Mort_IndicScript_Msg[verb] ); /* for the non-debugging */ - FT_UNUSED( glyphOffset ); /* case */ + FT_UNUSED( glyphOffset_p ); /* case */ markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); @@ -91,7 +91,7 @@ verb = (FT_UShort)( flags & 0x000F ); GXV_TRACE(( " IndicScript MorphRule for glyphOffset 0x%04x", - glyphOffset.u )); + glyphOffset_p->u )); GXV_TRACE(( " markFirst=%01d", markFirst )); GXV_TRACE(( " dontAdvance=%01d", dontAdvance )); GXV_TRACE(( " markLast=%01d", markLast )); diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c b/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c index 0575b1260ac..696d85032d0 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort1.c @@ -135,7 +135,7 @@ gxv_mort_subtable_type1_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -154,8 +154,8 @@ dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); reserved = (FT_Short)( flags & 0x3FFF ); - markOffset = (FT_Short)( glyphOffset.ul >> 16 ); - currentOffset = (FT_Short)( glyphOffset.ul ); + markOffset = (FT_Short)( glyphOffset_p->ul >> 16 ); + currentOffset = (FT_Short)( glyphOffset_p->ul ); if ( 0 < reserved ) { @@ -202,7 +202,7 @@ if ( dst_gid > valid->face->num_glyphs ) { - GXV_TRACE(( "substTable include toolarge gid[%d]=%d >" + GXV_TRACE(( "substTable include too large gid[%d]=%d >" " max defined gid #%d\n", i, dst_gid, valid->face->num_glyphs )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c b/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c index f19d15dab5d..6f77cf39ce7 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort2.c @@ -189,7 +189,7 @@ gxv_mort_subtable_type2_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -199,7 +199,7 @@ FT_UShort offset; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); FT_UNUSED( limit ); diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c b/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c index a04bc1efaf4..83470988c09 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort4.c @@ -40,12 +40,12 @@ static void gxv_mort_subtable_type4_lookupval_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); - gxv_glyphid_validate( value.u, valid ); + gxv_glyphid_validate( value_p->u, valid ); } /* @@ -78,7 +78,7 @@ static GXV_LookupValueDesc gxv_mort_subtable_type4_lookupfmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -88,7 +88,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->lookuptbl_head + offset; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c b/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c index a7cabc359fc..ec0bcb634d5 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmort5.c @@ -139,7 +139,7 @@ gxv_mort_subtable_type5_entry_validate( FT_Byte state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -168,8 +168,8 @@ currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); markedInsertCount = (FT_Byte)( flags & 0x001F ); - currentInsertList = (FT_UShort)( glyphOffset.ul >> 16 ); - markedInsertList = (FT_UShort)( glyphOffset.ul ); + currentInsertList = (FT_UShort)( glyphOffset->ul >> 16 ); + markedInsertList = (FT_UShort)( glyphOffset->ul ); if ( 0 != currentInsertList && 0 != currentInsertCount ) { diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c b/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c index 849d5e942a5..f8ba5b985d9 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmorx.c @@ -4,7 +4,8 @@ /* */ /* TrueTypeGX/AAT morx table validation (body). */ /* */ -/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ +/* Copyright 2005, 2008 by */ +/* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,8 +69,8 @@ FT_ULong length; FT_ULong coverage; FT_ULong subFeatureFlags; - FT_UInt type; - FT_UInt rest; + FT_ULong type; + FT_ULong rest; GXV_LIMIT_CHECK( 4 + 4 + 4 ); @@ -129,7 +130,7 @@ gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); p += valid->subtable_length; - if ( nSubtables >= 0x10000 ) + if ( nSubtables >= 0x10000L ) FT_INVALID_DATA; gxv_morx_subtables_validate( p, table + chainLength, diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c b/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c index ca92b6c3925..0159c5aef7a 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmorx0.c @@ -42,7 +42,7 @@ gxv_morx_subtable_type0_entry_validate( FT_UShort state, FT_UShort flags, - GXV_XStateTable_GlyphOffsetDesc glyphOffset, + GXV_XStateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -54,7 +54,7 @@ FT_UShort verb; FT_UNUSED( state ); - FT_UNUSED( glyphOffset ); + FT_UNUSED( glyphOffset_p ); FT_UNUSED( table ); FT_UNUSED( limit ); diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c b/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c index 331d4ccdab3..e1c162fa0c6 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmorx1.c @@ -103,7 +103,7 @@ gxv_morx_subtable_type1_entry_validate( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -127,8 +127,8 @@ reserved = (FT_UShort)( flags & 0x3FFF ); - markIndex = (FT_Short)( glyphOffset.ul >> 16 ); - currentIndex = (FT_Short)( glyphOffset.ul ); + markIndex = (FT_Short)( glyphOffset_p->ul >> 16 ); + currentIndex = (FT_Short)( glyphOffset_p->ul ); GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n", setMark, dontAdvance )); @@ -155,14 +155,14 @@ static void gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { FT_UNUSED( glyph ); /* for the non-debugging case */ - GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value.u )); + GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u )); - if ( value.u > valid->face->num_glyphs ) + if ( value_p->u > valid->face->num_glyphs ) FT_INVALID_GLYPH_ID; } @@ -170,7 +170,7 @@ static GXV_LookupValueDesc gxv_morx_subtable_type1_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -180,7 +180,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof ( FT_UShort ) ); p = valid->lookuptbl_head + offset; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c b/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c index 5cad5169c21..b4bb3353f69 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmorx2.c @@ -186,7 +186,7 @@ gxv_morx_subtable_type2_entry_validate( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -206,7 +206,7 @@ performAction = (FT_UShort)( ( flags >> 13 ) & 1 ); reserved = (FT_UShort)( flags & 0x1FFF ); - ligActionIndex = glyphOffset.u; + ligActionIndex = glyphOffset_p->u; if ( reserved > 0 ) GXV_TRACE(( " reserved 14bit is non-zero\n" )); diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c b/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c index d9115618c09..5e3a16437e2 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvmorx5.c @@ -136,7 +136,7 @@ gxv_morx_subtable_type5_entry_validate( FT_UShort state, FT_UShort flags, - GXV_StateTable_GlyphOffsetDesc glyphOffset, + GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) @@ -165,8 +165,8 @@ currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); markedInsertCount = (FT_Byte)( flags & 0x001F ); - currentInsertList = (FT_Byte) ( glyphOffset.ul >> 16 ); - markedInsertList = (FT_UShort)( glyphOffset.ul ); + currentInsertList = (FT_Byte) ( glyphOffset_p->ul >> 16 ); + markedInsertList = (FT_UShort)( glyphOffset_p->ul ); if ( currentInsertList && 0 != currentInsertCount ) gxv_morx_subtable_type5_InsertList_validate( currentInsertList, diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c b/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c index 8d6fe669f30..e1250609460 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvopbd.c @@ -67,18 +67,18 @@ static void gxv_opbd_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { /* offset in LookupTable is measured from the head of opbd table */ - FT_Bytes p = valid->root->base + value.u; + FT_Bytes p = valid->root->base + value_p->u; FT_Bytes limit = valid->root->limit; FT_Short delta_value; int i; - if ( value.u < GXV_OPBD_DATA( valueOffset_min ) ) - GXV_OPBD_DATA( valueOffset_min ) = value.u; + if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) + GXV_OPBD_DATA( valueOffset_min ) = value_p->u; for ( i = 0; i < 4; i++ ) { @@ -132,7 +132,7 @@ static GXV_LookupValueDesc gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -142,7 +142,7 @@ FT_UNUSED( valid ); /* XXX: check range? */ - value.u = (FT_UShort)( base_value.u + + value.u = (FT_UShort)( base_value_p->u + relative_gindex * 4 * sizeof ( FT_Short ) ); return value; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvprop.c b/lib/3rdparty/freetype/src/gxvalid/gxvprop.c index 010eeda4266..66c3ab74042 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvprop.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvprop.c @@ -168,10 +168,10 @@ static void gxv_prop_LookupValue_validate( FT_UShort glyph, - GXV_LookupValueDesc value, + GXV_LookupValueCPtr value_p, GXV_Validator valid ) { - gxv_prop_property_validate( value.u, glyph, valid ); + gxv_prop_property_validate( value_p->u, glyph, valid ); } @@ -204,7 +204,7 @@ static GXV_LookupValueDesc gxv_prop_LookupFmt4_transit( FT_UShort relative_gindex, - GXV_LookupValueDesc base_value, + GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator valid ) { @@ -214,7 +214,7 @@ GXV_LookupValueDesc value; /* XXX: check range? */ - offset = (FT_UShort)( base_value.u + + offset = (FT_UShort)( base_value_p->u + relative_gindex * sizeof( FT_UShort ) ); p = valid->lookuptbl_head + offset; limit = lookuptbl_limit; diff --git a/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c b/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c index 432ee4e2719..df3fd15c0b6 100644 --- a/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c +++ b/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c @@ -198,7 +198,7 @@ { FT_Bytes p = table; FT_Bytes limit = 0; - FT_UInt table_size; + FT_Offset table_size; GXV_ValidatorRec validrec; GXV_Validator valid = &validrec; diff --git a/lib/3rdparty/freetype/src/gxvalid/module.mk b/lib/3rdparty/freetype/src/gxvalid/module.mk index 44ef94addfa..9fd098e2c5e 100644 --- a/lib/3rdparty/freetype/src/gxvalid/module.mk +++ b/lib/3rdparty/freetype/src/gxvalid/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += GXVALID_MODULE define GXVALID_MODULE -$(OPEN_DRIVER)gxv_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, gxv_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)gxvalid $(ECHO_DRIVER_DESC)TrueTypeGX/AAT validation module$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/gzip/adler32.c b/lib/3rdparty/freetype/src/gzip/adler32.c index 36f6a432eaf..c53f9dd125d 100644 --- a/lib/3rdparty/freetype/src/gzip/adler32.c +++ b/lib/3rdparty/freetype/src/gzip/adler32.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: adler32.c,v 1.5 2007/06/01 06:56:17 wl Exp $ */ +/* @(#) $Id$ */ #include "zlib.h" diff --git a/lib/3rdparty/freetype/src/gzip/ftgzip.c b/lib/3rdparty/freetype/src/gzip/ftgzip.c index af2022d7f5a..6f0c515723e 100644 --- a/lib/3rdparty/freetype/src/gzip/ftgzip.c +++ b/lib/3rdparty/freetype/src/gzip/ftgzip.c @@ -8,7 +8,7 @@ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,7 +25,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include FT_GZIP_H -#include <string.h> +#include FT_CONFIG_STANDARD_LIBRARY_H #include FT_MODULE_ERRORS_H @@ -40,6 +40,10 @@ #ifdef FT_CONFIG_OPTION_USE_ZLIB +#ifdef FT_CONFIG_OPTION_PIC +#error "gzip code does not support PIC yet" +#endif + #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB #include <zlib.h> @@ -54,7 +58,9 @@ /* original ZLib. */ #define NO_DUMMY_DECL -#define MY_ZCALLOC +#ifndef USE_ZLIB_ZCALLOC +#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */ +#endif #include "zlib.h" @@ -117,7 +123,7 @@ } -#ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB +#if !defined( FT_CONFIG_OPTION_SYSTEM_ZLIB ) && !defined( USE_ZLIB_ZCALLOC ) local voidpf zcalloc ( voidpf opaque, @@ -134,7 +140,7 @@ ft_gzip_free( (FT_Memory)opaque, ptr ); } -#endif /* !SYSTEM_ZLIB */ +#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */ /***************************************************************************/ @@ -569,7 +575,7 @@ if ( error ) result = 0; - FT_Stream_Seek( stream, old_pos ); + (void)FT_Stream_Seek( stream, old_pos ); } return result; diff --git a/lib/3rdparty/freetype/src/gzip/inftrees.c b/lib/3rdparty/freetype/src/gzip/inftrees.c index 3c39aca6e3a..ef536521686 100644 --- a/lib/3rdparty/freetype/src/gzip/inftrees.c +++ b/lib/3rdparty/freetype/src/gzip/inftrees.c @@ -366,6 +366,9 @@ z_streamp z /* for messages */ if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed distance tree"; else if (r == Z_BUF_ERROR) { +#if 0 + { +#endif #ifdef PKZIP_BUG_WORKAROUND r = Z_OK; } diff --git a/lib/3rdparty/freetype/src/gzip/zconf.h b/lib/3rdparty/freetype/src/gzip/zconf.h index 3ccc3a66ab6..3abf0ba03b0 100644 --- a/lib/3rdparty/freetype/src/gzip/zconf.h +++ b/lib/3rdparty/freetype/src/gzip/zconf.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zconf.h,v 1.4 2007/06/01 06:56:17 wl Exp $ */ +/* @(#) $Id$ */ #ifndef _ZCONF_H #define _ZCONF_H @@ -60,6 +60,12 @@ # define MSDOS #endif +/* WinCE doesn't have errno.h */ +#ifdef _WIN32_WCE +# define NO_ERRNO_H +#endif + + /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). diff --git a/lib/3rdparty/freetype/src/gzip/zutil.c b/lib/3rdparty/freetype/src/gzip/zutil.c index 5ed2da08713..7ad0c1f81bb 100644 --- a/lib/3rdparty/freetype/src/gzip/zutil.c +++ b/lib/3rdparty/freetype/src/gzip/zutil.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zutil.c,v 1.3 2006/04/29 07:31:16 wl Exp $ */ +/* @(#) $Id$ */ #include "zutil.h" @@ -49,7 +49,7 @@ void zmemzero(dest, len) } #endif -#ifdef __TURBOC__ +#if defined( MSDOS ) && defined( __TURBOC__ ) && !defined( MY_ZCALLOC ) #if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) /* Small and medium model in Turbo C are for now limited to near allocation * with reduced MAX_WBITS and MAX_MEM_LEVEL @@ -126,10 +126,10 @@ void zcfree (voidpf opaque, voidpf ptr) Assert(0, "zcfree: ptr not found"); } #endif -#endif /* __TURBOC__ */ +#endif /* MSDOS && __TURBOC__ */ -#if defined(M_I86) && !defined(__32BIT__) +#if defined(M_I86) && !defined(__32BIT__) && !defined( MY_ZCALLOC ) /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC diff --git a/lib/3rdparty/freetype/src/gzip/zutil.h b/lib/3rdparty/freetype/src/gzip/zutil.h index 8e3c69a9f06..c9688cd9c04 100644 --- a/lib/3rdparty/freetype/src/gzip/zutil.h +++ b/lib/3rdparty/freetype/src/gzip/zutil.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: zutil.h,v 1.6 2007/06/01 06:56:17 wl Exp $ */ +/* @(#) $Id$ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H diff --git a/lib/3rdparty/freetype/src/lzw/ftlzw.c b/lib/3rdparty/freetype/src/lzw/ftlzw.c index 45fbf7b6ea1..6e57dedb971 100644 --- a/lib/3rdparty/freetype/src/lzw/ftlzw.c +++ b/lib/3rdparty/freetype/src/lzw/ftlzw.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2009, 2010 by */ /* Albert Chin-A-Young. */ /* */ /* Based on code in src/gzip/ftgzip.c, Copyright 2004 by */ @@ -27,8 +27,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include FT_LZW_H -#include <string.h> -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H #include FT_MODULE_ERRORS_H @@ -43,6 +42,10 @@ #ifdef FT_CONFIG_OPTION_USE_LZW +#ifdef FT_CONFIG_OPTION_PIC +#error "lzw code does not support PIC yet" +#endif + #include "ftzopen.h" @@ -119,13 +122,9 @@ zip->pos = 0; /* check and skip .Z header */ - { - stream = source; - - error = ft_lzw_check_header( source ); - if ( error ) - goto Exit; - } + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; /* initialize internal lzw variable */ ft_lzwstate_init( lzw, source ); diff --git a/lib/3rdparty/freetype/src/lzw/ftzopen.c b/lib/3rdparty/freetype/src/lzw/ftzopen.c index fc7831510d1..8bc65c8f57b 100644 --- a/lib/3rdparty/freetype/src/lzw/ftzopen.c +++ b/lib/3rdparty/freetype/src/lzw/ftzopen.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005, 2006, 2007 by David Turner. */ +/* Copyright 2005, 2006, 2007, 2009 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -113,8 +113,8 @@ { FT_Memory memory = state->memory; FT_Error error; - FT_UInt old_size = state->stack_size; - FT_UInt new_size = old_size; + FT_Offset old_size = state->stack_size; + FT_Offset new_size = old_size; new_size = new_size + ( new_size >> 1 ) + 4; @@ -332,6 +332,9 @@ while ( code >= 256U ) { + if ( !state->prefix ) + goto Eof; + FTLZW_STACK_PUSH( state->suffix[code - 256] ); code = state->prefix[code - 256]; } diff --git a/lib/3rdparty/freetype/src/lzw/ftzopen.h b/lib/3rdparty/freetype/src/lzw/ftzopen.h index 97881149c22..f7d2936be2f 100644 --- a/lib/3rdparty/freetype/src/lzw/ftzopen.h +++ b/lib/3rdparty/freetype/src/lzw/ftzopen.h @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005, 2006, 2007 by David Turner. */ +/* Copyright 2005, 2006, 2007, 2008 by David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -46,7 +46,7 @@ #define LZW_MASK( n ) ( ( 1U << (n) ) - 1U ) - typedef enum + typedef enum FT_LzwPhase_ { FT_LZW_PHASE_START = 0, FT_LZW_PHASE_CODE, @@ -109,7 +109,7 @@ * `free_ent', `num_bits' cannot grow larger than `max_bits'. */ - typedef struct _FT_LzwStateRec + typedef struct FT_LzwStateRec_ { FT_LzwPhase phase; FT_Int in_eof; @@ -118,7 +118,7 @@ FT_Int buf_offset; FT_Int buf_size; FT_Bool buf_clear; - FT_Int buf_total; + FT_Offset buf_total; FT_UInt max_bits; /* max code bits, from file header */ FT_Int block_mode; /* block mode flag, from file header */ @@ -137,7 +137,7 @@ FT_Byte* stack; /* character stack */ FT_UInt stack_top; - FT_UInt stack_size; + FT_Offset stack_size; FT_Byte stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */ FT_Stream source; /* source stream */ diff --git a/lib/3rdparty/freetype/src/otvalid/Jamfile b/lib/3rdparty/freetype/src/otvalid/Jamfile index 35a14c6ab94..b457143de4f 100644 --- a/lib/3rdparty/freetype/src/otvalid/Jamfile +++ b/lib/3rdparty/freetype/src/otvalid/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ; if $(FT2_MULTI) { - _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod ; + _sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod otvmath ; } else { diff --git a/lib/3rdparty/freetype/src/otvalid/module.mk b/lib/3rdparty/freetype/src/otvalid/module.mk index aa4db047d55..9cadde55e46 100644 --- a/lib/3rdparty/freetype/src/otvalid/module.mk +++ b/lib/3rdparty/freetype/src/otvalid/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += OTVALID_MODULE define OTVALID_MODULE -$(OPEN_DRIVER)otv_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, otv_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)otvalid $(ECHO_DRIVER_DESC)OpenType validation module$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/otvalid/otvalid.c b/lib/3rdparty/freetype/src/otvalid/otvalid.c index 2f85f601b66..d5c2b75abb6 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvalid.c +++ b/lib/3rdparty/freetype/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "otvgpos.c" #include "otvgsub.c" #include "otvjstf.c" +#include "otvmath.c" #include "otvmod.c" /* END */ diff --git a/lib/3rdparty/freetype/src/otvalid/otvalid.h b/lib/3rdparty/freetype/src/otvalid/otvalid.h index 38f030f3935..eb99b9cc48e 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvalid.h +++ b/lib/3rdparty/freetype/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ /* */ /* OpenType table validation (specification only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,7 @@ FT_BEGIN_HEADER otv_GDEF_validate( FT_Bytes table, FT_Bytes gsub, FT_Bytes gpos, + FT_UInt glyph_count, FT_Validator valid ); FT_LOCAL( void ) @@ -63,6 +64,11 @@ FT_BEGIN_HEADER FT_UInt glyph_count, FT_Validator valid ); + FT_LOCAL( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ); + FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/otvalid/otvbase.c b/lib/3rdparty/freetype/src/otvalid/otvbase.c index 8ad2238d6d6..d742d2dc95f 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvbase.c +++ b/lib/3rdparty/freetype/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,7 +62,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -297,7 +297,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; table_size = 6; diff --git a/lib/3rdparty/freetype/src/otvalid/otvcommn.c b/lib/3rdparty/freetype/src/otvalid/otvcommn.c index d94e4f3cb62..a4f885b51f8 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvcommn.c +++ b/lib/3rdparty/freetype/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,10 +39,12 @@ FT_LOCAL_DEF( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid ) + OTV_Validator valid, + FT_Int expected_count ) { FT_Bytes p = table; FT_UInt CoverageFormat; + FT_UInt total = 0; OTV_NAME_ENTER( "Coverage" ); @@ -57,6 +59,7 @@ case 1: /* CoverageFormat1 */ { FT_UInt GlyphCount; + FT_UInt i; GlyphCount = FT_NEXT_USHORT( p ); @@ -64,13 +67,25 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ + + for ( i = 0; i < GlyphCount; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + } + + total = GlyphCount; } break; case 2: /* CoverageFormat2 */ { FT_UInt n, RangeCount; - FT_UInt Start, End, StartCoverageIndex, total = 0, last = 0; + FT_UInt Start, End, StartCoverageIndex, last = 0; RangeCount = FT_NEXT_USHORT( p ); @@ -89,6 +104,9 @@ if ( Start > End || StartCoverageIndex != total ) FT_INVALID_DATA; + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + if ( n > 0 && Start <= last ) FT_INVALID_DATA; @@ -102,8 +120,11 @@ FT_INVALID_FORMAT; } - /* no need to check glyph indices used as input to coverage tables */ - /* since even invalid glyph indices return a meaningful result */ + /* Generally, a coverage table offset has an associated count field. */ + /* The number of glyphs in the table should match this field. If */ + /* there is no associated count, a value of -1 tells us not to check. */ + if ( expected_count != -1 && (FT_UInt)expected_count != total ) + FT_INVALID_DATA; OTV_EXIT; } @@ -215,18 +236,21 @@ { case 1: /* ClassDefFormat1 */ { + FT_UInt StartGlyph; FT_UInt GlyphCount; - p += 2; /* skip StartGlyph */ - - OTV_LIMIT_CHECK( 2 ); + OTV_LIMIT_CHECK( 4 ); + StartGlyph = FT_NEXT_USHORT( p ); GlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ + + if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; } break; @@ -252,6 +276,9 @@ if ( Start > End || ( n > 0 && Start <= last ) ) FT_INVALID_DATA; + if ( End >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + last = End; } } @@ -291,7 +318,10 @@ EndSize = FT_NEXT_USHORT( p ); DeltaFormat = FT_NEXT_USHORT( p ); - if ( DeltaFormat < 1 || DeltaFormat > 3 || EndSize < StartSize ) + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; + + if ( EndSize < StartSize ) FT_INVALID_DATA; count = EndSize - StartSize + 1; @@ -330,7 +360,7 @@ OTV_TRACE(( " (type %d)\n", LookupType )); - if ( LookupType == 0 || LookupType >= valid->type_count ) + if ( LookupType == 0 || LookupType > valid->type_count ) FT_INVALID_DATA; validate = valid->type_funcs[LookupType - 1]; @@ -657,7 +687,7 @@ OTV_TRACE(( " (Count = %d)\n", Count )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, Count ); OTV_LIMIT_CHECK( Count * 2 ); @@ -729,6 +759,7 @@ FT_INVALID_DATA; OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); + p += ( Count1 - 1 ) * 2; for ( ; Count2 > 0; Count2-- ) { @@ -824,7 +855,7 @@ OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + ClassDef, valid ); OTV_LIMIT_CHECK( ClassSetCount * 2 ); @@ -872,7 +903,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); for ( count1 = GlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); for ( ; Count > 0; Count-- ) { @@ -913,7 +944,7 @@ OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + BacktrackClassDef, valid ); otv_ClassDef_validate( table + InputClassDef, valid ); @@ -963,7 +994,7 @@ OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); InputGlyphCount = FT_NEXT_USHORT( p ); @@ -972,7 +1003,7 @@ OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); for ( count1 = InputGlyphCount; count1 > 0; count1-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -981,7 +1012,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); count2 = FT_NEXT_USHORT( p ); diff --git a/lib/3rdparty/freetype/src/otvalid/otvcommn.h b/lib/3rdparty/freetype/src/otvalid/otvcommn.h index be6ac69c284..898887fc954 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvcommn.h +++ b/lib/3rdparty/freetype/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (specification). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,27 +85,27 @@ FT_BEGIN_HEADER FT_INVALID_TOO_SHORT; \ FT_END_STMNT -#define OTV_SIZE_CHECK( _size ) \ - FT_BEGIN_STMNT \ - if ( _size > 0 && _size < table_size ) \ - { \ - if ( valid->root->level == FT_VALIDATE_PARANOID ) \ - FT_INVALID_OFFSET; \ - else \ - { \ - /* strip off `const' */ \ - FT_Byte* pp = (FT_Byte*)_size ## _p; \ - \ - \ - FT_TRACE3(( "\n" \ - "Invalid offset to optional table `%s'!\n" \ - "Set to zero.\n" \ - "\n", #_size )); \ - \ - /* always assume 16bit entities */ \ - _size = pp[0] = pp[1] = 0; \ - } \ - } \ +#define OTV_SIZE_CHECK( _size ) \ + FT_BEGIN_STMNT \ + if ( _size > 0 && _size < table_size ) \ + { \ + if ( valid->root->level == FT_VALIDATE_PARANOID ) \ + FT_INVALID_OFFSET; \ + else \ + { \ + /* strip off `const' */ \ + FT_Byte* pp = (FT_Byte*)_size ## _p; \ + \ + \ + FT_TRACE3(( "\n" \ + "Invalid offset to optional table `%s'" \ + " set to zero.\n" \ + "\n", #_size )); \ + \ + /* always assume 16bit entities */ \ + _size = pp[0] = pp[1] = 0; \ + } \ + } \ FT_END_STMNT @@ -192,12 +192,12 @@ FT_BEGIN_HEADER valid->func[2] = OTV_FUNC( z ); \ FT_END_STMNT -#define OTV_INIT do ; while ( 0 ) -#define OTV_ENTER do ; while ( 0 ) -#define OTV_NAME_ENTER( name ) do ; while ( 0 ) -#define OTV_EXIT do ; while ( 0 ) +#define OTV_INIT do { } while ( 0 ) +#define OTV_ENTER do { } while ( 0 ) +#define OTV_NAME_ENTER( name ) do { } while ( 0 ) +#define OTV_EXIT do { } while ( 0 ) -#define OTV_TRACE( s ) do ; while ( 0 ) +#define OTV_TRACE( s ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_TRACE */ @@ -215,7 +215,8 @@ FT_BEGIN_HEADER FT_LOCAL( void ) otv_Coverage_validate( FT_Bytes table, - OTV_Validator valid ); + OTV_Validator valid, + FT_Int expected_count ); /* return first covered glyph */ FT_LOCAL( FT_UInt ) diff --git a/lib/3rdparty/freetype/src/otvalid/otvgdef.c b/lib/3rdparty/freetype/src/otvalid/otvgdef.c index 7d24902e881..3633ad0de18 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvgdef.c +++ b/lib/3rdparty/freetype/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -61,7 +61,7 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, GlyphCount ); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; @@ -126,7 +126,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -141,10 +141,13 @@ /*************************************************************************/ /*************************************************************************/ + /* sets valid->glyph_count */ + FT_LOCAL_DEF( void ) otv_GDEF_validate( FT_Bytes table, FT_Bytes gsub, FT_Bytes gpos, + FT_UInt glyph_count, FT_Validator ftvalid ) { OTV_ValidatorRec validrec; @@ -183,6 +186,8 @@ else table_size = 10; /* OpenType < 1.2 */ + valid->glyph_count = glyph_count; + OTV_OPTIONAL_OFFSET( GlyphClassDef ); OTV_SIZE_CHECK( GlyphClassDef ); if ( GlyphClassDef ) diff --git a/lib/3rdparty/freetype/src/otvalid/otvgpos.c b/lib/3rdparty/freetype/src/otvalid/otvgpos.c index ed347053d65..49b46183a32 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvgpos.c +++ b/lib/3rdparty/freetype/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -124,8 +124,8 @@ Array1 = FT_NEXT_USHORT( p ); Array2 = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage1, valid ); - otv_Coverage_validate( table + Coverage2, valid ); + otv_Coverage_validate( table + Coverage1, valid, -1 ); + otv_Coverage_validate( table + Coverage2, valid, -1 ); otv_MarkArray_validate( table + Array1, valid ); @@ -191,7 +191,7 @@ #endif if ( format >= 0x100 ) - FT_INVALID_DATA; + FT_INVALID_FORMAT; for ( count = 4; count > 0; count-- ) { @@ -209,7 +209,7 @@ { if ( format & 1 ) { - FT_UInt table_size; + FT_PtrDist table_size; OTV_OPTIONAL_TABLE( device ); @@ -294,7 +294,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -376,7 +376,7 @@ Coverage = FT_NEXT_USHORT( p ); ValueFormat = FT_NEXT_USHORT( p ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ } break; @@ -395,7 +395,7 @@ len_value = otv_value_length( ValueFormat ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, ValueCount ); OTV_LIMIT_CHECK( ValueCount * len_value ); @@ -409,7 +409,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -498,7 +498,7 @@ OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); OTV_LIMIT_CHECK( PairSetCount * 2 ); @@ -530,7 +530,7 @@ len_value1 = otv_value_length( ValueFormat1 ); len_value2 = otv_value_length( ValueFormat2 ); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, -1 ); otv_ClassDef_validate( table + ClassDef1, valid ); otv_ClassDef_validate( table + ClassDef2, valid ); @@ -558,7 +558,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -605,7 +605,7 @@ OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); OTV_LIMIT_CHECK( EntryExitCount * 4 ); @@ -629,7 +629,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -644,7 +644,10 @@ /*************************************************************************/ /*************************************************************************/ - /* sets valid->extra2 (0) */ + /* UNDOCUMENTED (in OpenType 1.5): */ + /* BaseRecord tables can contain NULL pointers. */ + + /* sets valid->extra2 (1) */ static void otv_MarkBasePos_validate( FT_Bytes table, @@ -664,13 +667,13 @@ switch ( PosFormat ) { case 1: - valid->extra2 = 0; + valid->extra2 = 1; OTV_NEST2( MarkBasePosFormat1, BaseArray ); OTV_RUN( table, valid ); break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -711,7 +714,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -752,7 +755,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -811,7 +814,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -872,7 +875,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -908,7 +911,8 @@ { case 1: /* ExtensionPosFormat1 */ { - FT_UInt ExtensionLookupType, ExtensionOffset; + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; OTV_Validate_Func validate; @@ -925,7 +929,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -989,7 +993,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/lib/3rdparty/freetype/src/otvalid/otvgsub.c b/lib/3rdparty/freetype/src/otvalid/otvgsub.c index 91dae0bb161..ed499d1e92d 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvgsub.c +++ b/lib/3rdparty/freetype/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,7 +68,7 @@ Coverage = table + FT_NEXT_USHORT( p ); DeltaGlyphID = FT_NEXT_SHORT( p ); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, -1 ); idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; if ( idx < 0 ) @@ -91,19 +91,19 @@ OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); - otv_Coverage_validate( table + Coverage, valid ); + otv_Coverage_validate( table + Coverage, valid, GlyphCount ); OTV_LIMIT_CHECK( GlyphCount * 2 ); /* Substitute */ for ( ; GlyphCount > 0; GlyphCount-- ) if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) - FT_INVALID_DATA; + FT_INVALID_GLYPH_ID; } break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -144,7 +144,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -185,7 +185,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -259,7 +259,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -318,7 +318,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -379,7 +379,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -415,7 +415,8 @@ { case 1: /* ExtensionSubstFormat1 */ { - FT_UInt ExtensionLookupType, ExtensionOffset; + FT_UInt ExtensionLookupType; + FT_ULong ExtensionOffset; OTV_Validate_Func validate; @@ -434,7 +435,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -476,12 +477,12 @@ OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); - otv_Coverage_validate( Coverage, valid ); + otv_Coverage_validate( Coverage, valid, -1 ); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); @@ -490,7 +491,7 @@ OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) - otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid ); + otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); GlyphCount = FT_NEXT_USHORT( p ); @@ -509,7 +510,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -560,7 +561,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/lib/3rdparty/freetype/src/otvalid/otvjstf.c b/lib/3rdparty/freetype/src/otvalid/otvjstf.c index 80b8dd66043..a616a23432c 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvjstf.c +++ b/lib/3rdparty/freetype/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -222,7 +222,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; JstfScriptCount = FT_NEXT_USHORT( p ); diff --git a/lib/3rdparty/freetype/src/otvalid/otvmath.c b/lib/3rdparty/freetype/src/otvalid/otvmath.c new file mode 100644 index 00000000000..50ed10cf284 --- /dev/null +++ b/lib/3rdparty/freetype/src/otvalid/otvmath.c @@ -0,0 +1,452 @@ +/***************************************************************************/ +/* */ +/* otvmath.c */ +/* */ +/* OpenType MATH table validation (body). */ +/* */ +/* Copyright 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by George Williams. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_otvmath + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TYPOGRAPHIC CONSTANTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathConstants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( "MathConstants" ); + + /* 56 constants, 51 have device tables */ + OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); + table_size = 2 * ( 56 + 51 ); + + p += 4 * 2; /* First 4 constants have no device tables */ + for ( i = 0; i < 51; ++i ) + { + p += 2; /* skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH ITALICS CORRECTION *****/ + /***** MATH TOP ACCENT ATTACHMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int isItalic ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size ; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + FT_UNUSED( isItalic ); /* only used if tracing is active */ + + + OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" + : "MathTopAccentAttachment" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt ); + table_size = 4 + 4 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH KERNING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathKern_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "MathKern" );*/ + + OTV_LIMIT_CHECK( 2 ); + + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt + 2 ); + table_size = 4 + 4 * cnt; + + /* Heights */ + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + /* One more Kerning value */ + for ( i = 0; i < cnt + 1; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + static void + otv_MathKernInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, j, cnt, table_size; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( MKRecordOffset ); + + + OTV_NAME_ENTER( "MathKernInfo" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * cnt ); + table_size = 4 + 8 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid, cnt ); + + for ( i = 0; i < cnt; ++i ) + { + for ( j = 0; j < 4; ++j ) + { + OTV_OPTIONAL_OFFSET( MKRecordOffset ); + OTV_SIZE_CHECK( MKRecordOffset ); + if ( MKRecordOffset ) + otv_MathKern_validate( table + MKRecordOffset, valid ); + } + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH INFO *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathGlyphInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; + FT_UInt ExtendedShapeCoverage, MathKernInfo; + + + OTV_NAME_ENTER( "MathGlyphInfo" ); + + OTV_LIMIT_CHECK( 8 ); + + MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); + MathTopAccentAttachment = FT_NEXT_USHORT( p ); + ExtendedShapeCoverage = FT_NEXT_USHORT( p ); + MathKernInfo = FT_NEXT_USHORT( p ); + + if ( MathItalicsCorrectionInfo ) + otv_MathItalicsCorrectionInfo_validate( + table + MathItalicsCorrectionInfo, valid, TRUE ); + + /* Italic correction and Top Accent Attachment have the same format */ + if ( MathTopAccentAttachment ) + otv_MathItalicsCorrectionInfo_validate( + table + MathTopAccentAttachment, valid, FALSE ); + + if ( ExtendedShapeCoverage ) { + OTV_NAME_ENTER( "ExtendedShapeCoverage" ); + otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 ); + OTV_EXIT; + } + + if ( MathKernInfo ) + otv_MathKernInfo_validate( table + MathKernInfo, valid ); + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH CONSTRUCTION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_GlyphAssembly_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt pcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "GlyphAssembly" ); */ + + OTV_LIMIT_CHECK( 6 ); + + p += 2; /* Skip the Italics Correction value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + pcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * pcnt ); + table_size = 6 + 8 * pcnt; + + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + + for ( i = 0; i < pcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2*4; /* skip the Start, End, Full, and Flags fields */ + } + + /* OTV_EXIT; */ + } + + + static void + otv_MathGlyphConstruction_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, table_size; + FT_UInt i; + + OTV_OPTIONAL_TABLE( GlyphAssembly ); + + + /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( GlyphAssembly ); + vcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * vcnt ); + table_size = 4 + 4 * vcnt; + + for ( i = 0; i < vcnt; ++i ) + { + FT_UInt gid; + + + gid = FT_NEXT_USHORT( p ); + if ( gid >= valid->glyph_count ) + FT_INVALID_GLYPH_ID; + p += 2; /* skip the size */ + } + + OTV_SIZE_CHECK( GlyphAssembly ); + if ( GlyphAssembly ) + otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathVariants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, hcnt, i, table_size; + + OTV_OPTIONAL_TABLE( VCoverage ); + OTV_OPTIONAL_TABLE( HCoverage ); + OTV_OPTIONAL_TABLE( Offset ); + + + OTV_NAME_ENTER( "MathVariants" ); + + OTV_LIMIT_CHECK( 10 ); + + p += 2; /* Skip the MinConnectorOverlap constant */ + OTV_OPTIONAL_OFFSET( VCoverage ); + OTV_OPTIONAL_OFFSET( HCoverage ); + vcnt = FT_NEXT_USHORT( p ); + hcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); + table_size = 10 + 2 * vcnt + 2 * hcnt; + + OTV_SIZE_CHECK( VCoverage ); + if ( VCoverage ) + otv_Coverage_validate( table + VCoverage, valid, vcnt ); + + OTV_SIZE_CHECK( HCoverage ); + if ( HCoverage ) + otv_Coverage_validate( table + HCoverage, valid, hcnt ); + + for ( i = 0; i < vcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + for ( i = 0; i < hcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt MathConstants, MathGlyphInfo, MathVariants; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating MATH table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + MathConstants = FT_NEXT_USHORT( p ); + MathGlyphInfo = FT_NEXT_USHORT( p ); + MathVariants = FT_NEXT_USHORT( p ); + + valid->glyph_count = glyph_count; + + otv_MathConstants_validate( table + MathConstants, + valid ); + otv_MathGlyphInfo_validate( table + MathGlyphInfo, + valid ); + otv_MathVariants_validate ( table + MathVariants, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/lib/3rdparty/freetype/src/otvalid/otvmod.c b/lib/3rdparty/freetype/src/otvalid/otvmod.c index 157272f1ae9..3248564560c 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvmod.c +++ b/lib/3rdparty/freetype/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,12 +79,27 @@ FT_Byte* volatile gpos; FT_Byte* volatile gsub; FT_Byte* volatile jstf; + FT_Byte* volatile math; FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ULong len_math; + FT_UInt num_glyphs = (FT_UInt)face->num_glyphs; FT_ValidatorRec volatile valid; - base = gdef = gpos = gsub = jstf = NULL; - len_base = len_gdef = len_gpos = len_gsub = len_jstf = 0; + base = gdef = gpos = gsub = jstf = math = NULL; + len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; + + /* + * XXX: OpenType tables cannot handle 32-bit glyph index, + * although broken TrueType can have 32-bit glyph index. + */ + if ( face->num_glyphs > 0xFFFFL ) + { + FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ", + face->num_glyphs )); + FT_TRACE1(( "are not handled by OpenType tables\n" )); + num_glyphs = 0xFFFF; + } /* load tables */ @@ -123,6 +138,13 @@ goto Exit; } + if ( ot_flags & FT_VALIDATE_MATH ) + { + error = otv_load_table( face, TTAG_MATH, &math, &len_math ); + if ( error ) + goto Exit; + } + /* validate tables */ if ( base ) @@ -139,7 +161,7 @@ { ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GPOS_validate( gpos, face->num_glyphs, &valid ); + otv_GPOS_validate( gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -149,7 +171,7 @@ { ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GSUB_validate( gsub, face->num_glyphs, &valid ); + otv_GSUB_validate( gsub, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -159,7 +181,7 @@ { ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_GDEF_validate( gdef, gsub, gpos, &valid ); + otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -169,7 +191,17 @@ { ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT ); if ( ft_setjmp( valid.jump_buffer ) == 0 ) - otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid ); + otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + + if ( math ) + { + ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_MATH_validate( math, num_glyphs, &valid ); error = valid.error; if ( error ) goto Exit; @@ -192,6 +224,12 @@ FT_FREE( gsub ); FT_FREE( jstf ); } + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( math ); /* Can't return this as API is frozen */ + } return error; } diff --git a/lib/3rdparty/freetype/src/otvalid/otvmod.h b/lib/3rdparty/freetype/src/otvalid/otvmod.h index 1bfc1899fe3..573b2a0c4b9 100644 --- a/lib/3rdparty/freetype/src/otvalid/otvmod.h +++ b/lib/3rdparty/freetype/src/otvalid/otvmod.h @@ -27,6 +27,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class; diff --git a/lib/3rdparty/freetype/src/otvalid/rules.mk b/lib/3rdparty/freetype/src/otvalid/rules.mk index 48f12336f79..53bd41e5e7d 100644 --- a/lib/3rdparty/freetype/src/otvalid/rules.mk +++ b/lib/3rdparty/freetype/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004 by +# Copyright 2004, 2007 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -31,14 +31,15 @@ OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ $(OTV_DIR)/otvgpos.c \ $(OTV_DIR)/otvgsub.c \ $(OTV_DIR)/otvjstf.c \ + $(OTV_DIR)/otvmath.c \ $(OTV_DIR)/otvmod.c # OTV driver headers # -OTV_DRV_H := $(OTV_DIR)/otvalid.h \ - $(OTV_DIR)/otverror.h \ +OTV_DRV_H := $(OTV_DIR)/otvalid.h \ $(OTV_DIR)/otvcommn.h \ - $(OTV_DIR)/otvgpos.h \ + $(OTV_DIR)/otverror.h \ + $(OTV_DIR)/otvgpos.h \ $(OTV_DIR)/otvmod.h diff --git a/lib/3rdparty/freetype/src/pcf/module.mk b/lib/3rdparty/freetype/src/pcf/module.mk index 0c51cd6fc42..df383ff0fbe 100644 --- a/lib/3rdparty/freetype/src/pcf/module.mk +++ b/lib/3rdparty/freetype/src/pcf/module.mk @@ -27,7 +27,7 @@ FTMODULE_H_COMMANDS += PCF_DRIVER define PCF_DRIVER -$(OPEN_DRIVER)pcf_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, pcf_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/pcf/pcf.h b/lib/3rdparty/freetype/src/pcf/pcf.h index 9d2d8e0e429..1cd56c13a40 100644 --- a/lib/3rdparty/freetype/src/pcf/pcf.h +++ b/lib/3rdparty/freetype/src/pcf/pcf.h @@ -72,8 +72,8 @@ FT_BEGIN_HEADER union { FT_String* atom; - FT_Long integer; - FT_ULong cardinal; + FT_Long l; + FT_ULong ul; } value; diff --git a/lib/3rdparty/freetype/src/pcf/pcfdrivr.c b/lib/3rdparty/freetype/src/pcf/pcfdrivr.c index c0f0e49ca12..b34e542aeb0 100644 --- a/lib/3rdparty/freetype/src/pcf/pcfdrivr.c +++ b/lib/3rdparty/freetype/src/pcf/pcfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for pcf files - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 by + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -111,7 +111,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; mid = ( min + max ) >> 1; @@ -140,7 +140,7 @@ THE SOFTWARE. PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; FT_UInt min, max, mid; - FT_UInt32 charcode = *acharcode + 1; + FT_ULong charcode = *acharcode + 1; FT_UInt result = 0; @@ -149,7 +149,7 @@ THE SOFTWARE. while ( min < max ) { - FT_UInt32 code; + FT_ULong code; mid = ( min + max ) >> 1; @@ -175,7 +175,14 @@ THE SOFTWARE. } Exit: - *acharcode = charcode; + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); + *acharcode = 0; + /* XXX: result should be changed to indicate an overflow error */ + } + else + *acharcode = (FT_UInt32)charcode; return result; } @@ -187,17 +194,24 @@ THE SOFTWARE. pcf_cmap_init, pcf_cmap_done, pcf_cmap_char_index, - pcf_cmap_char_next + pcf_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; FT_CALLBACK_DEF( void ) PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ { - PCF_Face face = (PCF_Face)pcfface; - FT_Memory memory = FT_FACE_MEMORY( face ); + PCF_Face face = (PCF_Face)pcfface; + FT_Memory memory; + if ( !face ) + return; + + memory = FT_FACE_MEMORY( face ); + FT_FREE( face->encodings ); FT_FREE( face->metrics ); @@ -259,17 +273,26 @@ THE SOFTWARE. error = pcf_load_font( stream, face ); if ( error ) { - FT_Error error2; - - PCF_Face_Done( pcfface ); - /* this didn't work, try gzip support! */ - error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); - if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) - goto Fail; +#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ + defined( FT_CONFIG_OPTION_USE_LZW ) - error = error2; +#ifdef FT_CONFIG_OPTION_USE_ZLIB + { + FT_Error error2; + + + /* this didn't work, try gzip support! */ + error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); + if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) + goto Fail; + + error = error2; + } +#endif /* FT_CONFIG_OPTION_USE_ZLIB */ + +#ifdef FT_CONFIG_OPTION_USE_LZW if ( error ) { FT_Error error3; @@ -281,29 +304,26 @@ THE SOFTWARE. goto Fail; error = error3; - if ( error ) - goto Fail; - - face->gzip_source = stream; - pcfface->stream = &face->gzip_stream; - - stream = pcfface->stream; - - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; } - else - { - face->gzip_source = stream; - pcfface->stream = &face->gzip_stream; +#endif /* FT_CONFIG_OPTION_USE_LZW */ - stream = pcfface->stream; + if ( error ) + goto Fail; - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; - } + face->gzip_source = stream; + pcfface->stream = &face->gzip_stream; + + stream = pcfface->stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + +#else /* !(FT_CONFIG_OPTION_USE_ZLIB || FT_CONFIG_OPTION_USE_LZW) */ + + goto Fail; + +#endif } /* set up charmap */ @@ -402,7 +422,7 @@ THE SOFTWARE. switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( bsize->y_ppem + 32 ) >> 6 ) + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) error = PCF_Err_Ok; break; @@ -431,11 +451,11 @@ THE SOFTWARE. FT_Int32 load_flags ) { PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); - FT_Stream stream = face->root.stream; + FT_Stream stream; FT_Error error = PCF_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; PCF_Metric metric; - int bytes; + FT_Offset bytes; FT_UNUSED( load_flags ); @@ -448,6 +468,8 @@ THE SOFTWARE. goto Exit; } + stream = face->root.stream; + if ( glyph_index > 0 ) glyph_index--; @@ -563,12 +585,17 @@ THE SOFTWARE. } else { + if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + { + FT_TRACE1(( "pcf_get_bdf_property: " )); + FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + } /* Apparently, the PCF driver loads all properties as signed integers! * This really doesn't seem to be a problem, because this is * sufficient for any meaningful values. */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = prop->value.integer; + aproperty->u.integer = (FT_Int32)prop->value.l; } return 0; } diff --git a/lib/3rdparty/freetype/src/pcf/pcfdrivr.h b/lib/3rdparty/freetype/src/pcf/pcfdrivr.h index 7ddf697e164..a81d7309e5f 100644 --- a/lib/3rdparty/freetype/src/pcf/pcfdrivr.h +++ b/lib/3rdparty/freetype/src/pcf/pcfdrivr.h @@ -33,6 +33,10 @@ THE SOFTWARE. FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/pcf/pcfread.c b/lib/3rdparty/freetype/src/pcf/pcfread.c index b9123cf574f..08becf99ce3 100644 --- a/lib/3rdparty/freetype/src/pcf/pcfread.c +++ b/lib/3rdparty/freetype/src/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -32,7 +32,6 @@ THE SOFTWARE. #include FT_INTERNAL_OBJECTS_H #include "pcf.h" -#include "pcfdrivr.h" #include "pcfread.h" #include "pcferror.h" @@ -48,7 +47,7 @@ THE SOFTWARE. #define FT_COMPONENT trace_pcfread -#if defined( FT_DEBUG_LEVEL_TRACE ) +#ifdef FT_DEBUG_LEVEL_TRACE static const char* const tableNames[] = { "prop", "accl", "mtrcs", "bmps", "imtrcs", @@ -152,7 +151,7 @@ THE SOFTWARE. break; } -#if defined( FT_DEBUG_LEVEL_TRACE ) +#ifdef FT_DEBUG_LEVEL_TRACE { FT_UInt i, j; @@ -290,13 +289,13 @@ THE SOFTWARE. static FT_Error pcf_seek_to_table_type( FT_Stream stream, PCF_Table tables, - FT_Int ntables, + FT_ULong ntables, /* same as PCF_Toc->count */ FT_ULong type, FT_ULong *aformat, FT_ULong *asize ) { FT_Error error = PCF_Err_Invalid_File_Format; - FT_Int i; + FT_ULong i; for ( i = 0; i < ntables; i++ ) @@ -328,10 +327,10 @@ THE SOFTWARE. static FT_Bool pcf_has_table_type( PCF_Table tables, - FT_Int ntables, + FT_ULong ntables, /* same as PCF_Toc->count */ FT_ULong type ) { - FT_Int i; + FT_ULong i; for ( i = 0; i < ntables; i++ ) @@ -400,7 +399,7 @@ THE SOFTWARE. { PCF_ParseProperty props = 0; PCF_Property properties; - FT_UInt nprops, i; + FT_ULong nprops, i; FT_ULong format, size; FT_Error error; FT_Memory memory = FT_FACE(face)->memory; @@ -434,7 +433,10 @@ THE SOFTWARE. if ( error ) goto Bail; - FT_TRACE4(( " nprop = %d\n", nprops )); + FT_TRACE4(( " nprop = %d (truncate %d props)\n", + (int)nprops, nprops - (int)nprops )); + + nprops = (int)nprops; /* rough estimate */ if ( nprops > size / PCF_PROPERTY_SIZE ) @@ -443,7 +445,7 @@ THE SOFTWARE. goto Bail; } - face->nprops = nprops; + face->nprops = (int)nprops; if ( FT_NEW_ARRAY( props, nprops ) ) goto Bail; @@ -470,7 +472,11 @@ THE SOFTWARE. if ( nprops & 3 ) { i = 4 - ( nprops & 3 ); - FT_Stream_Skip( stream, i ); + if ( FT_STREAM_SKIP( i ) ) + { + error = PCF_Err_Invalid_Stream_Skip; + goto Bail; + } } if ( PCF_BYTE_ORDER( format ) == MSBFirst ) @@ -539,9 +545,9 @@ THE SOFTWARE. } else { - properties[i].value.integer = props[i].value; + properties[i].value.l = props[i].value; - FT_TRACE4(( " %d\n", properties[i].value.integer )); + FT_TRACE4(( " %d\n", properties[i].value.l )); } } @@ -623,7 +629,7 @@ THE SOFTWARE. metrics = face->metrics; for ( i = 0; i < nmetrics; i++ ) { - pcf_get_metric( stream, format, metrics + i ); + error = pcf_get_metric( stream, format, metrics + i ); metrics[i].bits = 0; @@ -658,7 +664,7 @@ THE SOFTWARE. FT_Long* offsets; FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; - int nbitmaps, i, sizebitmaps = 0; + FT_ULong nbitmaps, i, sizebitmaps = 0; error = pcf_seek_to_table_type( stream, @@ -689,7 +695,8 @@ THE SOFTWARE. FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); - if ( nbitmaps != face->nmetrics ) + /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ + if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) return PCF_Err_Invalid_File_Format; if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) @@ -735,8 +742,8 @@ THE SOFTWARE. if ( ( offsets[i] < 0 ) || ( (FT_ULong)offsets[i] > size ) ) { - FT_ERROR(( "pcf_get_bitmaps:")); - FT_ERROR(( " invalid offset to bitmap data of glyph %d\n", i )); + FT_TRACE0(( "pcf_get_bitmaps:" + " invalid offset to bitmap data of glyph %d\n", i )); } else face->metrics[i].bits = stream->pos + offsets[i]; @@ -989,9 +996,9 @@ THE SOFTWARE. PCF_Property prop; - int nn, len; - char* strings[4] = { NULL, NULL, NULL, NULL }; - int lengths[4]; + size_t nn, len; + char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t lengths[4]; face->style_flags = 0; @@ -1073,7 +1080,7 @@ THE SOFTWARE. /* add_style_name and setwidth_name */ if ( nn == 0 || nn == 3 ) { - int mm; + size_t mm; for ( mm = 0; mm < len; mm++ ) @@ -1198,7 +1205,7 @@ THE SOFTWARE. prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); + bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); else bsize->width = (FT_Short)( bsize->height * 2/3 ); @@ -1206,19 +1213,19 @@ THE SOFTWARE. if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = - (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); + (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); prop = pcf_find_property( face, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.integer << 6; + bsize->y_ppem = (FT_Short)prop->value.l << 6; prop = pcf_find_property( face, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.integer; + resolution_x = (FT_Short)prop->value.l; prop = pcf_find_property( face, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.integer; + resolution_y = (FT_Short)prop->value.l; if ( bsize->y_ppem == 0 ) { diff --git a/lib/3rdparty/freetype/src/pcf/pcfutil.c b/lib/3rdparty/freetype/src/pcf/pcfutil.c index 67ddbe8890b..b91274f935b 100644 --- a/lib/3rdparty/freetype/src/pcf/pcfutil.c +++ b/lib/3rdparty/freetype/src/pcf/pcfutil.c @@ -42,9 +42,9 @@ in this Software without prior written authorization from The Open Group. FT_LOCAL_DEF( void ) BitOrderInvert( unsigned char* buf, - int nbytes ) + size_t nbytes ) { - for ( ; --nbytes >= 0; buf++ ) + for ( ; nbytes > 0; nbytes--, buf++ ) { unsigned int val = *buf; @@ -64,7 +64,7 @@ in this Software without prior written authorization from The Open Group. FT_LOCAL_DEF( void ) TwoByteSwap( unsigned char* buf, - int nbytes ) + size_t nbytes ) { unsigned char c; @@ -83,7 +83,7 @@ in this Software without prior written authorization from The Open Group. FT_LOCAL_DEF( void ) FourByteSwap( unsigned char* buf, - int nbytes ) + size_t nbytes ) { unsigned char c; diff --git a/lib/3rdparty/freetype/src/pcf/pcfutil.h b/lib/3rdparty/freetype/src/pcf/pcfutil.h index 1557be3e800..ce10fb541d5 100644 --- a/lib/3rdparty/freetype/src/pcf/pcfutil.h +++ b/lib/3rdparty/freetype/src/pcf/pcfutil.h @@ -37,15 +37,15 @@ FT_BEGIN_HEADER FT_LOCAL( void ) BitOrderInvert( unsigned char* buf, - int nbytes ); + size_t nbytes ); FT_LOCAL( void ) TwoByteSwap( unsigned char* buf, - int nbytes ); + size_t nbytes ); FT_LOCAL( void ) FourByteSwap( unsigned char* buf, - int nbytes ); + size_t nbytes ); FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/pcf/rules.mk b/lib/3rdparty/freetype/src/pcf/rules.mk index 1ad4ba897a3..78641528fab 100644 --- a/lib/3rdparty/freetype/src/pcf/rules.mk +++ b/lib/3rdparty/freetype/src/pcf/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 2000, 2001, 2003 by +# Copyright (C) 2000, 2001, 2003, 2008 by # Francesco Zappa Nardelli # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -35,15 +35,14 @@ PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) # pcf driver sources (i.e., C files) # -PCF_DRV_SRC := $(PCF_DIR)/pcfread.c \ - $(PCF_DIR)/pcfdrivr.c \ +PCF_DRV_SRC := $(PCF_DIR)/pcfdrivr.c \ + $(PCF_DIR)/pcfread.c \ $(PCF_DIR)/pcfutil.c # pcf driver headers # -PCF_DRV_H := $(PCF_DIR)/pcf.h \ - $(PCF_DIR)/pcfdrivr.h \ - $(PCF_DIR)/pcfutil.h \ +PCF_DRV_H := $(PCF_DRV_SRC:%.c=%.h) \ + $(PCF_DIR)/pcf.h \ $(PCF_DIR)/pcferror.h # pcf driver object(s) diff --git a/lib/3rdparty/freetype/src/pfr/module.mk b/lib/3rdparty/freetype/src/pfr/module.mk index 53ab34aa9fe..8d1d28a9d23 100644 --- a/lib/3rdparty/freetype/src/pfr/module.mk +++ b/lib/3rdparty/freetype/src/pfr/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PFR_DRIVER define PFR_DRIVER -$(OPEN_DRIVER)pfr_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, pfr_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/pfr/pfrcmap.c b/lib/3rdparty/freetype/src/pfr/pfrcmap.c index c8faee04364..9c8f9ed8eb3 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrcmap.c +++ b/lib/3rdparty/freetype/src/pfr/pfrcmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (body). */ /* */ -/* Copyright 2002, 2007 by */ +/* Copyright 2002, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,8 @@ #include "pfrcmap.h" #include "pfrobjs.h" -#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" FT_CALLBACK_DEF( FT_Error ) @@ -87,7 +88,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) pfr_cmap_char_next( PFR_CMap cmap, FT_UInt32 *pchar_code ) { @@ -156,7 +157,9 @@ (FT_CMap_InitFunc) pfr_cmap_init, (FT_CMap_DoneFunc) pfr_cmap_done, (FT_CMap_CharIndexFunc)pfr_cmap_char_index, - (FT_CMap_CharNextFunc) pfr_cmap_char_next + (FT_CMap_CharNextFunc) pfr_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/lib/3rdparty/freetype/src/pfr/pfrdrivr.c b/lib/3rdparty/freetype/src/pfr/pfrdrivr.c index 40206720efb..15cca9854e4 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrdrivr.c +++ b/lib/3rdparty/freetype/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2006 by */ +/* Copyright 2002, 2003, 2004, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -66,10 +66,16 @@ FT_Pos *anadvance ) { PFR_Face face = (PFR_Face)pfrface; - FT_Error error = PFR_Err_Bad_Argument; + FT_Error error = PFR_Err_Invalid_Argument; *anadvance = 0; + + if ( !gindex ) + goto Exit; + + gindex--; + if ( face ) { PFR_PhyFont phys = &face->phy_font; @@ -82,6 +88,7 @@ } } + Exit: return error; } diff --git a/lib/3rdparty/freetype/src/pfr/pfrdrivr.h b/lib/3rdparty/freetype/src/pfr/pfrdrivr.h index 36f1205b772..da0a1aa6344 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrdrivr.h +++ b/lib/3rdparty/freetype/src/pfr/pfrdrivr.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; diff --git a/lib/3rdparty/freetype/src/pfr/pfrgload.c b/lib/3rdparty/freetype/src/pfr/pfrgload.c index 3bb173302d4..6fe6e4225ab 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrgload.c +++ b/lib/3rdparty/freetype/src/pfr/pfrgload.c @@ -595,7 +595,7 @@ if ( org_count + count > glyph->max_subs ) { - FT_UInt new_max = ( org_count + count + 3 ) & -4; + FT_UInt new_max = ( org_count + count + 3 ) & (FT_UInt)-4; if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) diff --git a/lib/3rdparty/freetype/src/pfr/pfrload.c b/lib/3rdparty/freetype/src/pfr/pfrload.c index 1ee2c1f8c8b..bc5c035f3da 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrload.c +++ b/lib/3rdparty/freetype/src/pfr/pfrload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -428,7 +428,8 @@ Too_Short: error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" )); + FT_ERROR(( "pfr_extra_item_load_bitmap_info:" + " invalid bitmap info table\n" )); goto Exit; } @@ -506,7 +507,8 @@ Too_Short: error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" )); + FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + " invalid stem snaps table\n" )); goto Exit; } @@ -603,8 +605,8 @@ FT_FREE( item ); error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " - "invalid kerning pairs table\n" )); + FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" + " invalid kerning pairs table\n" )); goto Exit; } @@ -714,7 +716,8 @@ { FT_Error error; FT_Memory memory = stream->memory; - FT_UInt flags, num_aux; + FT_UInt flags; + FT_ULong num_aux; FT_Byte* p; FT_Byte* limit; diff --git a/lib/3rdparty/freetype/src/pfr/pfrobjs.c b/lib/3rdparty/freetype/src/pfr/pfrobjs.c index 180446d737d..56d617d880a 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrobjs.c +++ b/lib/3rdparty/freetype/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,10 +41,15 @@ FT_LOCAL_DEF( void ) pfr_face_done( FT_Face pfrface ) /* PFR_Face */ { - PFR_Face face = (PFR_Face)pfrface; - FT_Memory memory = pfrface->driver->root.memory; + PFR_Face face = (PFR_Face)pfrface; + FT_Memory memory; + if ( !face ) + return; + + memory = pfrface->driver->root.memory; + /* we don't want dangling pointers */ pfrface->family_name = NULL; pfrface->style_name = NULL; diff --git a/lib/3rdparty/freetype/src/pfr/pfrsbit.c b/lib/3rdparty/freetype/src/pfr/pfrsbit.c index 45ff6663b36..d2f17dc9ceb 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrsbit.c +++ b/lib/3rdparty/freetype/src/pfr/pfrsbit.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (body). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002, 2003, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -600,8 +600,8 @@ /* get the bitmap metrics */ { - FT_Long xpos, ypos, advance; - FT_UInt xsize, ysize, format; + FT_Long xpos = 0, ypos = 0, advance = 0; + FT_UInt xsize = 0, ysize = 0, format = 0; FT_Byte* p; @@ -630,18 +630,35 @@ &xpos, &ypos, &xsize, &ysize, &advance, &format ); + + /* + * XXX: on 16bit system, we return an error for huge bitmap + * which causes a size truncation, because truncated + * size properties makes bitmap glyph broken. + */ + if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX ) + { + FT_TRACE1(( "pfr_slot_load_bitmap:" )); + FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n", + xpos, ypos )); + error = PFR_Err_Invalid_Pixel_Size; + } + if ( !error ) { glyph->root.format = FT_GLYPH_FORMAT_BITMAP; /* Set up glyph bitmap and metrics */ + + /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */ glyph->root.bitmap.width = (FT_Int)xsize; glyph->root.bitmap.rows = (FT_Int)ysize; - glyph->root.bitmap.pitch = (FT_Long)( xsize + 7 ) >> 3; + glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3; glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; - glyph->root.metrics.width = (FT_Long)xsize << 6; - glyph->root.metrics.height = (FT_Long)ysize << 6; + /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ + glyph->root.metrics.width = (FT_Pos)xsize << 6; + glyph->root.metrics.height = (FT_Pos)ysize << 6; glyph->root.metrics.horiBearingX = xpos << 6; glyph->root.metrics.horiBearingY = ypos << 6; glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); @@ -649,8 +666,9 @@ glyph->root.metrics.vertBearingY = 0; glyph->root.metrics.vertAdvance = size->root.metrics.height; - glyph->root.bitmap_left = xpos; - glyph->root.bitmap_top = ypos + ysize; + /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */ + glyph->root.bitmap_left = (FT_Int)xpos; + glyph->root.bitmap_top = (FT_Int)(ypos + ysize); /* Allocate and read bitmap data */ { diff --git a/lib/3rdparty/freetype/src/pfr/pfrtypes.h b/lib/3rdparty/freetype/src/pfr/pfrtypes.h index c0ae04253a2..918310814c5 100644 --- a/lib/3rdparty/freetype/src/pfr/pfrtypes.h +++ b/lib/3rdparty/freetype/src/pfr/pfrtypes.h @@ -200,7 +200,7 @@ FT_BEGIN_HEADER FT_Byte flags; FT_Short base_adj; FT_UInt pair_size; - FT_UInt32 offset; + FT_Offset offset; FT_UInt32 pair1; FT_UInt32 pair2; @@ -252,7 +252,7 @@ FT_BEGIN_HEADER FT_UInt blue_scale; FT_UInt num_chars; - FT_UInt32 chars_offset; + FT_Offset chars_offset; PFR_Char chars; FT_UInt num_kern_pairs; @@ -260,7 +260,7 @@ FT_BEGIN_HEADER PFR_KernItem* kern_items_tail; /* not part of the spec, but used during load */ - FT_UInt32 bct_offset; + FT_Long bct_offset; FT_Byte* cursor; } PFR_PhyFontRec, *PFR_PhyFont; diff --git a/lib/3rdparty/freetype/src/psaux/afmparse.c b/lib/3rdparty/freetype/src/psaux/afmparse.c index 0528fe6ff4f..91a17e2362e 100644 --- a/lib/3rdparty/freetype/src/psaux/afmparse.c +++ b/lib/3rdparty/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,6 @@ #include <ft2build.h> #include FT_FREETYPE_H #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "afmparse.h" #include "psconv.h" @@ -367,11 +366,11 @@ FT_LOCAL_DEF( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ) + FT_UInt n ) { AFM_Stream stream = parser->stream; char* str; - FT_Int i; + FT_UInt i; if ( n > AFM_MAX_ARGUMENTS ) @@ -379,7 +378,7 @@ for ( i = 0; i < n; i++ ) { - FT_UInt len; + FT_Offset len; AFM_Value val = vals + i; @@ -441,7 +440,7 @@ FT_LOCAL_DEF( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ) + FT_Offset* len ) { AFM_Stream stream = parser->stream; char* key = 0; /* make stupid compiler happy */ @@ -489,7 +488,7 @@ } if ( len ) - *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key ) + *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) : 0; return key; @@ -498,7 +497,7 @@ static AFM_Token afm_tokenize( const char* key, - FT_UInt len ) + FT_Offset len ) { int n; @@ -586,7 +585,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_TrackKern tk; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -672,7 +671,12 @@ FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 ); - return (int)( index1 - index2 ); + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; } @@ -682,7 +686,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_KernPair kp; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -770,9 +774,9 @@ static FT_Error afm_parse_kern_data( AFM_Parser parser ) { - FT_Error error; - char* key; - FT_UInt len; + FT_Error error; + char* key; + FT_Offset len; while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) @@ -814,8 +818,8 @@ FT_UInt n, AFM_Token end_section ) { - char* key; - FT_UInt len; + char* key; + FT_Offset len; while ( n-- > 0 ) @@ -846,7 +850,7 @@ AFM_FontInfo fi = parser->FontInfo; FT_Error error = PSaux_Err_Syntax_Error; char* key; - FT_UInt len; + FT_Offset len; FT_Int metrics_sets = 0; diff --git a/lib/3rdparty/freetype/src/psaux/afmparse.h b/lib/3rdparty/freetype/src/psaux/afmparse.h index c2fce75c86e..de2a530b2f0 100644 --- a/lib/3rdparty/freetype/src/psaux/afmparse.h +++ b/lib/3rdparty/freetype/src/psaux/afmparse.h @@ -71,13 +71,13 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ); + FT_UInt n ); /* read the next key from the next line or column */ FT_LOCAL( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ); + FT_Offset* len ); FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/psaux/module.mk b/lib/3rdparty/freetype/src/psaux/module.mk index 5431522084f..42bf6f51999 100644 --- a/lib/3rdparty/freetype/src/psaux/module.mk +++ b/lib/3rdparty/freetype/src/psaux/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PSAUX_MODULE define PSAUX_MODULE -$(OPEN_DRIVER)psaux_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, psaux_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/psaux/psauxmod.h b/lib/3rdparty/freetype/src/psaux/psauxmod.h index 92ac0560484..35e042dbce7 100644 --- a/lib/3rdparty/freetype/src/psaux/psauxmod.h +++ b/lib/3rdparty/freetype/src/psaux/psauxmod.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; diff --git a/lib/3rdparty/freetype/src/psaux/psconv.c b/lib/3rdparty/freetype/src/psaux/psconv.c index 3bbeab6d256..1531d8f0fb5 100644 --- a/lib/3rdparty/freetype/src/psaux/psconv.c +++ b/lib/3rdparty/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,10 +18,8 @@ #include <ft2build.h> #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "psconv.h" -#include "psobjs.h" #include "psauxerr.h" @@ -187,10 +185,18 @@ if ( c < 0 || c >= 10 ) break; - if ( divider < 10000000L ) + if ( !integral && power_ten > 0 ) { + power_ten--; decimal = decimal * 10 + c; - divider *= 10; + } + else + { + if ( divider < 10000000L ) + { + decimal = decimal * 10 + c; + divider *= 10; + } } } } @@ -233,7 +239,7 @@ PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -328,7 +334,7 @@ PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -417,7 +423,7 @@ PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ) { FT_Byte* p; diff --git a/lib/3rdparty/freetype/src/psaux/psconv.h b/lib/3rdparty/freetype/src/psaux/psconv.h index e51124185d7..84854ba0d16 100644 --- a/lib/3rdparty/freetype/src/psaux/psconv.h +++ b/lib/3rdparty/freetype/src/psaux/psconv.h @@ -46,20 +46,20 @@ FT_BEGIN_HEADER PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); #endif FT_LOCAL( FT_UInt ) PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); FT_LOCAL( FT_UInt ) PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ); diff --git a/lib/3rdparty/freetype/src/psaux/psobjs.c b/lib/3rdparty/freetype/src/psaux/psobjs.c index 957085668be..fe8398ae388 100644 --- a/lib/3rdparty/freetype/src/psaux/psobjs.c +++ b/lib/3rdparty/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include <ft2build.h> #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "psobjs.h" #include "psconv.h" @@ -169,17 +170,23 @@ void* object, FT_PtrDist length ) { - if ( idx < 0 || idx > table->max_elems ) + if ( idx < 0 || idx >= table->max_elems ) { FT_ERROR(( "ps_table_add: invalid index\n" )); return PSaux_Err_Invalid_Argument; } + if ( length < 0 ) + { + FT_ERROR(( "ps_table_add: invalid length\n" )); + return PSaux_Err_Invalid_Argument; + } + /* grow the base block if needed */ if ( table->cursor + length > table->capacity ) { FT_Error error; - FT_Offset new_size = table->capacity; + FT_Offset new_size = table->capacity; FT_Long in_offset; @@ -376,7 +383,7 @@ /* skip octal escape or ignore backslash */ for ( i = 0; i < 3 && cur < limit; ++i ) { - if ( ! IS_OCTAL_DIGIT( *cur ) ) + if ( !IS_OCTAL_DIGIT( *cur ) ) break; ++cur; @@ -558,8 +565,8 @@ cur++; if ( cur >= limit || *cur != '>' ) /* >> */ { - FT_ERROR(( "ps_parser_skip_PS_token: " - "unexpected closing delimiter `>'\n" )); + FT_ERROR(( "ps_parser_skip_PS_token:" + " unexpected closing delimiter `>'\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -584,9 +591,10 @@ Exit: if ( cur == parser->cursor ) { - FT_ERROR(( "ps_parser_skip_PS_token: " - "current token is `%c', which is self-delimiting " - "but invalid at this point\n", + FT_ERROR(( "ps_parser_skip_PS_token:" + " current token is `%c' which is self-delimiting\n" + " " + " but invalid at this point\n", *cur )); error = PSaux_Err_Invalid_File_Format; @@ -1147,8 +1155,10 @@ } else { - FT_ERROR(( "ps_parser_load_field: expected a name or string " - "but found token of type %d instead\n", + FT_ERROR(( "ps_parser_load_field:" + " expected a name or string\n" + " " + " but found token of type %d instead\n", token.type )); error = PSaux_Err_Invalid_File_Format; goto Exit; @@ -1185,8 +1195,8 @@ if ( result < 0 ) { - FT_ERROR(( "ps_parser_load_field: " - "expected four integers in bounding box\n" )); + FT_ERROR(( "ps_parser_load_field:" + " expected four integers in bounding box\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -1259,8 +1269,9 @@ old_cursor = parser->cursor; old_limit = parser->limit; - /* we store the elements count if necessary */ - if ( field->type != T1_FIELD_TYPE_BBOX ) + /* we store the elements count if necessary; */ + /* we further assume that `count_offset' can't be zero */ + if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = (FT_Byte)num_elements; @@ -1302,7 +1313,7 @@ FT_LOCAL_DEF( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ) { @@ -1483,12 +1494,6 @@ builder->hints_funcs = glyph->internal->glyph_hints; } - if ( size ) - { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; @@ -1550,16 +1555,9 @@ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - if ( builder->shift ) - { - x >>= 16; - y >>= 16; - } - point->x = x; - point->y = y; + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; } @@ -1640,27 +1638,24 @@ t1_builder_close_contour( T1_Builder builder ) { FT_Outline* outline = builder->current; + FT_Int first; if ( !outline ) return; - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ if ( outline->n_points > 1 ) { - FT_Int first = 0; FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - /* `delete' last point only if it coincides with the first */ /* point and it is not a control point (which can happen). */ if ( p1->x == p2->x && p1->y == p2->y ) @@ -1669,8 +1664,18 @@ } if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } } diff --git a/lib/3rdparty/freetype/src/psaux/psobjs.h b/lib/3rdparty/freetype/src/psaux/psobjs.h index c2cbf2c79b3..e380c60dabb 100644 --- a/lib/3rdparty/freetype/src/psaux/psobjs.h +++ b/lib/3rdparty/freetype/src/psaux/psobjs.h @@ -111,7 +111,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); diff --git a/lib/3rdparty/freetype/src/psaux/t1cmap.c b/lib/3rdparty/freetype/src/psaux/t1cmap.c index 29346869660..f933e4da88d 100644 --- a/lib/3rdparty/freetype/src/psaux/t1cmap.c +++ b/lib/3rdparty/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002, 2003, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -95,7 +95,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_std_char_next( T1_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -135,7 +135,9 @@ (FT_CMap_InitFunc) t1_cmap_standard_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -154,7 +156,9 @@ (FT_CMap_InitFunc) t1_cmap_expert_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -175,7 +179,7 @@ cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 ); + cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); @@ -209,7 +213,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_custom_char_next( T1_CMapCustom cmap, FT_UInt32 *pchar_code ) { @@ -245,7 +249,9 @@ (FT_CMap_InitFunc) t1_cmap_custom_init, (FT_CMap_DoneFunc) t1_cmap_custom_done, (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -306,7 +312,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { @@ -326,7 +332,9 @@ (FT_CMap_InitFunc) t1_cmap_unicode_init, (FT_CMap_DoneFunc) t1_cmap_unicode_done, (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/lib/3rdparty/freetype/src/psaux/t1decode.c b/lib/3rdparty/freetype/src/psaux/t1decode.c index f790643f961..31554ff1ba7 100644 --- a/lib/3rdparty/freetype/src/psaux/t1decode.c +++ b/lib/3rdparty/freetype/src/psaux/t1decode.c @@ -4,7 +4,8 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +18,7 @@ #include <ft2build.h> +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_OUTLINE_H @@ -144,7 +146,8 @@ FT_String* name = (FT_String*)decoder->glyph_names[n]; - if ( name && name[0] == glyph_name[0] && + if ( name && + name[0] == glyph_name[0] && ft_strcmp( name, glyph_name ) == 0 ) return n; } @@ -193,26 +196,52 @@ #endif FT_Vector left_bearing, advance; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return PSaux_Err_Syntax_Error; + } /* seac weirdness */ adx += decoder->builder.left_bearing.x; /* `glyph_names' is set to 0 for CID fonts which do not */ /* include an encoding. How can we deal with these? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( decoder->glyph_names == 0 && + !face->root.internal->incremental_interface ) +#else if ( decoder->glyph_names == 0 ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " glyph names table not available in this font!\n" )); + FT_ERROR(( "t1operator_seac:" + " glyph names table not available in this font\n" )); return PSaux_Err_Syntax_Error; } - bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); - achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + } if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "t1operator_seac:" + " invalid seac character code arguments\n" )); return PSaux_Err_Syntax_Error; } @@ -243,8 +272,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)( adx - asb ); - subg->arg2 = (FT_Int)ady; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -260,7 +289,10 @@ FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, bchar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -278,7 +310,11 @@ /* Now load `achar' on top of */ /* the base outline */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, achar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -327,9 +363,15 @@ FT_Pos x, y, orig_x, orig_y; FT_Int known_othersubr_result_cnt = 0; FT_Int unknown_othersubr_result_cnt = 0; + FT_Bool large_int; + FT_Fixed seed; T1_Hints_Funcs hinter; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + /* we don't want to touch the source code -- use macro trick */ #define start_point t1_builder_start_point @@ -339,6 +381,16 @@ #define add_contour t1_builder_add_contour #define close_contour t1_builder_close_contour + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + /* First of all, initialize the decoder */ decoder->top = decoder->stack; decoder->zone = decoder->zones; @@ -351,15 +403,15 @@ /* a font that reads BuildCharArray without setting */ /* its values first is buggy, but ... */ FT_ASSERT( ( decoder->len_buildchar == 0 ) == - ( decoder->buildchar == NULL ) ); + ( decoder->buildchar == NULL ) ); if ( decoder->len_buildchar > 0 ) - memset( &decoder->buildchar[0], - 0, - sizeof( decoder->buildchar[0] ) * - decoder->len_buildchar ); + ft_memset( &decoder->buildchar[0], + 0, + sizeof( decoder->buildchar[0] ) * decoder->len_buildchar ); - FT_TRACE4(( "\nStart charstring\n" )); + FT_TRACE4(( "\n" + "Start charstring\n" )); zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; @@ -374,18 +426,26 @@ if ( hinter ) hinter->open( hinter->hints ); + large_int = FALSE; + /* now, execute loop */ while ( ip < limit ) { FT_Long* top = decoder->top; T1_Operator op = op_none; - FT_Long value = 0; + FT_Int32 value = 0; FT_ASSERT( known_othersubr_result_cnt == 0 || unknown_othersubr_result_cnt == 0 ); - FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif /*********************************************************************/ /* */ @@ -456,8 +516,8 @@ case 12: if ( ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+EOF)\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+EOF)\n" )); goto Syntax_Error; } @@ -492,8 +552,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+%d)\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+%d)\n", ip[-1] )); goto Syntax_Error; } @@ -502,42 +562,69 @@ case 255: /* four bytes integer */ if ( ip + 4 > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } - value = (FT_Int32)( ((FT_Long)ip[0] << 24) | - ((FT_Long)ip[1] << 16) | - ((FT_Long)ip[2] << 8 ) | - ip[3] ); + value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) | + ( (FT_Long)ip[1] << 16 ) | + ( (FT_Long)ip[2] << 8 ) | + ip[3] ); ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like `<large1> <large2> <num> div <num> div' or */ + /* <large1> <large2> <num> div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + else + { + if ( !large_int ) + value <<= 16; + } + break; default: if ( ip[-1] >= 32 ) { if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; + value = (FT_Int32)ip[-1] - 139; else { if ( ++ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } if ( ip[-2] < 251 ) - value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; + value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); } + + if ( !large_int ) + value <<= 16; } else { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid byte (%d)\n", ip[-1] )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid byte (%d)\n", ip[-1] )); goto Syntax_Error; } } @@ -559,6 +646,14 @@ } } + if ( large_int && !( op == op_none || op == op_div ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + /*********************************************************************/ /* */ /* Push value on stack, or process operator */ @@ -568,11 +663,16 @@ { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); goto Syntax_Error; } - FT_TRACE4(( " %ld", value )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( large_int ) + FT_TRACE4(( " %ld", value )); + else + FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) )); +#endif *top++ = value; decoder->top = top; @@ -583,15 +683,18 @@ FT_Int arg_cnt; - FT_TRACE4(( " callothersubr" )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " callothersubr\n" )); + bol = TRUE; +#endif if ( top - decoder->stack < 2 ) goto Stack_Underflow; top -= 2; - subr_no = (FT_Int)top[1]; - arg_cnt = (FT_Int)top[0]; + subr_no = (FT_Int)( top[1] >> 16 ); + arg_cnt = (FT_Int)( top[0] >> 16 ); /***********************************************************/ /* */ @@ -668,8 +771,8 @@ if ( decoder->flex_state == 0 || decoder->num_flex_vectors != 7 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected flex end\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected flex end\n" )); goto Syntax_Error; } @@ -685,7 +788,6 @@ if ( hinter ) hinter->reset( hinter->hints, builder->current->n_points ); - break; case 12: @@ -708,16 +810,16 @@ if ( !blend ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected multiple masters operator!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected multiple masters operator\n" )); goto Syntax_Error; } num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "incorrect number of mm arguments\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " incorrect number of multiple masters arguments\n" )); goto Syntax_Error; } @@ -753,12 +855,6 @@ break; } -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS - - /* We cannot yet enable these since currently */ - /* our T1 stack stores integers which lack the */ - /* precision to express the values */ - case 19: /* <idx> 1 19 callothersubr */ /* => replace elements starting from index cvi( <idx> ) */ @@ -771,16 +867,16 @@ if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); - if ( idx < 0 || - idx + blend->num_designs > decoder->face->len_buildchar ) + if ( idx < 0 || + idx + blend->num_designs > decoder->len_buildchar ) goto Unexpected_OtherSubr; - memcpy( &decoder->buildchar[idx], - blend->weight_vector, - blend->num_designs * - sizeof( blend->weight_vector[ 0 ] ) ); + ft_memcpy( &decoder->buildchar[idx], + blend->weight_vector, + blend->num_designs * + sizeof( blend->weight_vector[0] ) ); } break; @@ -812,7 +908,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] *= top[1]; /* XXX (over|under)flow */ + top[0] = FT_MulFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -823,24 +919,23 @@ if ( arg_cnt != 2 || top[1] == 0 ) goto Unexpected_OtherSubr; - top[0] /= top[1]; /* XXX (over|under)flow */ + top[0] = FT_DivFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; -#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */ - case 24: - /* <val> <idx> 2 24 callothersubr */ - /* => set BuildCharArray[cvi( <idx> )] = <val> */ + /* <val> <idx> 2 24 callothersubr */ + /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 2 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[1]; + idx = (FT_Int)( top[1] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -850,17 +945,18 @@ break; case 25: - /* <idx> 1 25 callothersubr pop */ - /* => push BuildCharArray[cvi( idx )] */ - /* onto T1 stack */ + /* <idx> 1 25 callothersubr pop */ + /* ==> push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -876,13 +972,13 @@ /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */ /* leave mark on T1 stack */ /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */ - XXX who has left his mark on the (PostScript) stack ?; + XXX which routine has left its mark on the (PostScript) stack?; break; #endif case 27: /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */ - /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ + /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ /* otherwise push <res2> */ if ( arg_cnt != 4 ) goto Unexpected_OtherSubr; @@ -893,28 +989,40 @@ known_othersubr_result_cnt = 1; break; -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS case 28: /* 0 28 callothersubr pop */ /* => push random value from interval [0, 1) onto stack */ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - top[0] = FT_rand(); + { + FT_Fixed Rand; + + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + top[0] = Rand; + + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + } + known_othersubr_result_cnt = 1; break; -#endif default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unknown othersubr [%d %d], wish me luck!\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unknown othersubr [%d %d], wish me luck\n", arg_cnt, subr_no )); unknown_othersubr_result_cnt = arg_cnt; break; Unexpected_OtherSubr: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid othersubr [%d %d]!\n", arg_cnt, subr_no )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); goto Syntax_Error; } @@ -951,9 +1059,9 @@ default: if ( top - decoder->stack != num_args ) - FT_TRACE0(( "t1_decoder_parse_charstrings: " - "too much operands on the stack " - "(seen %d, expected %d)\n", + FT_TRACE0(( "t1_decoder_parse_charstrings:" + " too much operands on the stack" + " (seen %d, expected %d)\n", top - decoder->stack, num_args )); break; } @@ -965,28 +1073,26 @@ switch ( op ) { case op_endchar: - FT_TRACE4(( " endchar" )); + FT_TRACE4(( " endchar\n" )); close_contour( builder ); /* close hints recording session */ if ( hinter ) { - if (hinter->close( hinter->hints, builder->current->n_points )) + if ( hinter->close( hinter->hints, builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, - (PSH_Globals) builder->hints_globals, + (PSH_Globals)builder->hints_globals, decoder->hint_mode ); } /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); - FT_TRACE4(( "\n" )); - /* the compiler should optimize away this empty loop but ... */ #ifdef FT_DEBUG_LEVEL_TRACE @@ -1020,8 +1126,8 @@ builder->advance.x = top[1]; builder->advance.y = 0; - orig_x = builder->last.x = x = builder->pos_x + top[0]; - orig_y = builder->last.y = y = builder->pos_y; + orig_x = x = builder->pos_x + top[0]; + orig_y = y = builder->pos_y; FT_UNUSED( orig_y ); @@ -1034,9 +1140,12 @@ break; case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], top[2], - (FT_Int)top[3], (FT_Int)top[4] ); + return t1operator_seac( decoder, + top[0], + top[1], + top[2], + (FT_Int)( top[3] >> 16 ), + (FT_Int)( top[4] >> 16 ) ); case op_sbw: FT_TRACE4(( " sbw" )); @@ -1048,8 +1157,8 @@ builder->advance.x = top[2]; builder->advance.y = top[3]; - builder->last.x = x = builder->pos_x + top[0]; - builder->last.y = y = builder->pos_y + top[1]; + x = builder->pos_x + top[0]; + y = builder->pos_y + top[1]; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1062,10 +1171,11 @@ case op_closepath: FT_TRACE4(( " closepath" )); - close_contour( builder ); - if ( !( builder->parse_state == T1_Parse_Have_Path || - builder->parse_state == T1_Parse_Have_Moveto ) ) - goto Syntax_Error; + /* if there is no path, `closepath' is a no-op */ + if ( builder->parse_state == T1_Parse_Have_Path || + builder->parse_state == T1_Parse_Have_Moveto ) + close_contour( builder ); + builder->parse_state = T1_Parse_Have_Width; break; @@ -1134,7 +1244,7 @@ break; case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); + FT_TRACE4(( " rrcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) @@ -1193,16 +1303,13 @@ case op_div: FT_TRACE4(( " div" )); - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" )); - goto Syntax_Error; - } + /* if `large_int' is set, we divide unscaled numbers; */ + /* otherwise, we divide numbers in 16.16 format -- */ + /* in both cases, it is the same operation */ + *top = FT_DivFix( top[0], top[1] ); + ++top; + + large_int = FALSE; break; case op_callsubr: @@ -1212,18 +1319,18 @@ FT_TRACE4(( " callsubr" )); - idx = (FT_Int)top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid subrs index\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid subrs index\n" )); goto Syntax_Error; } if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "too many nested subrs\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " too many nested subrs\n" )); goto Syntax_Error; } @@ -1250,8 +1357,8 @@ if ( !zone->base ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invoking empty subrs!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -1273,8 +1380,8 @@ if ( unknown_othersubr_result_cnt == 0 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "no more operands for othersubr!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no more operands for othersubr\n" )); goto Syntax_Error; } @@ -1287,7 +1394,8 @@ if ( zone <= decoder->zones ) { - FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected return\n" )); goto Syntax_Error; } @@ -1311,7 +1419,6 @@ /* top[0] += builder->left_bearing.y; */ hinter->stem( hinter->hints, 1, top ); } - break; case op_hstem3: @@ -1320,19 +1427,17 @@ /* record horizontal counter-controlled hints */ if ( hinter ) hinter->stem3( hinter->hints, 1, top ); - break; case op_vstem: FT_TRACE4(( " vstem" )); - /* record vertical hint */ + /* record vertical hint */ if ( hinter ) { top[0] += orig_x; hinter->stem( hinter->hints, 0, top ); } - break; case op_vstem3: @@ -1354,20 +1459,28 @@ case op_setcurrentpoint: FT_TRACE4(( " setcurrentpoint" )); - /* From the T1 specs, section 6.4: */ + /* From the T1 specification, section 6.4: */ /* */ /* The setcurrentpoint command is used only in */ /* conjunction with results from OtherSubrs procedures. */ - /* known_othersubr_result_cnt != 0 is already handled above */ + /* known_othersubr_result_cnt != 0 is already handled */ + /* above. */ + + /* Note, however, that both Ghostscript and Adobe */ + /* Distiller handle this situation by silently ignoring */ + /* the inappropriate `setcurrentpoint' instruction. So */ + /* we do the same. */ +#if 0 + if ( decoder->flex_state != 1 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected `setcurrentpoint'\n" )); - + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected `setcurrentpoint'\n" )); goto Syntax_Error; } else +#endif decoder->flex_state = 0; break; @@ -1377,8 +1490,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unhandled opcode %d\n", op )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unhandled opcode %d\n", op )); goto Syntax_Error; } @@ -1389,6 +1502,11 @@ decoder->top = top; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( "\n" )); + bol = TRUE; +#endif + } /* general operator processing */ } /* while ip < limit */ @@ -1437,8 +1555,8 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "t1_decoder_init: " )); - FT_ERROR(( "the `psnames' module is not available\n" )); + FT_ERROR(( "t1_decoder_init:" + " the `psnames' module is not available\n" )); return PSaux_Err_Unimplemented_Feature; } diff --git a/lib/3rdparty/freetype/src/pshinter/Jamfile b/lib/3rdparty/freetype/src/pshinter/Jamfile index 769dcc4b296..779f1b0b828 100644 --- a/lib/3rdparty/freetype/src/pshinter/Jamfile +++ b/lib/3rdparty/freetype/src/pshinter/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; if $(FT2_MULTI) { - _sources = pshrec pshglob pshalgo pshmod ; + _sources = pshrec pshglob pshalgo pshmod pshpic ; } else { diff --git a/lib/3rdparty/freetype/src/pshinter/module.mk b/lib/3rdparty/freetype/src/pshinter/module.mk index cd171d03552..ed24eb7fa89 100644 --- a/lib/3rdparty/freetype/src/pshinter/module.mk +++ b/lib/3rdparty/freetype/src/pshinter/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PSHINTER_MODULE define PSHINTER_MODULE -$(OPEN_DRIVER)pshinter_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, pshinter_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/pshinter/pshalgo.c b/lib/3rdparty/freetype/src/pshinter/pshalgo.c index 505d95c5720..417dcee547a 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshalgo.c +++ b/lib/3rdparty/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -103,7 +103,7 @@ if ( idx >= table->max_hints ) { - FT_ERROR(( "psh_hint_table_record: invalid hint index %d\n", idx )); + FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx )); return; } @@ -137,7 +137,7 @@ if ( table->num_hints < table->max_hints ) table->sort_global[table->num_hints++] = hint; else - FT_ERROR(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); + FT_TRACE0(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); } @@ -230,7 +230,7 @@ FT_UInt idx; - FT_ERROR(( "psh_hint_table_init: missing/incorrect hint masks!\n" )); + FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" )); count = table->max_hints; for ( idx = 0; idx < count; idx++ ) @@ -282,8 +282,8 @@ { hint2 = sort[0]; if ( psh_hint_overlap( hint, hint2 ) ) - FT_ERROR(( "psh_hint_table_activate_mask:" - " found overlapping hints\n" )) + FT_TRACE0(( "psh_hint_table_activate_mask:" + " found overlapping hints\n" )) } #else count2 = 0; @@ -295,8 +295,8 @@ if ( count < table->max_hints ) table->sort[count++] = hint; else - FT_ERROR(( "psh_hint_tableactivate_mask:" - " too many active hints\n" )); + FT_TRACE0(( "psh_hint_tableactivate_mask:" + " too many active hints\n" )); } } } @@ -898,7 +898,7 @@ #ifdef DEBUG_ZONES -#include <stdio.h> +#include FT_CONFIG_STANDARD_LIBRARY_H static void psh_print_zone( PSH_Zone zone ) @@ -2223,15 +2223,22 @@ FT_Fixed x_scale = dim_x->scale_mult; FT_Fixed y_scale = dim_y->scale_mult; + FT_Fixed old_x_scale = x_scale; + FT_Fixed old_y_scale = y_scale; + FT_Fixed scaled; FT_Fixed fitted; + FT_Bool rescale = FALSE; + scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); fitted = FT_PIX_ROUND( scaled ); if ( fitted != 0 && scaled != fitted ) { + rescale = TRUE; + y_scale = FT_MulDiv( y_scale, fitted, scaled ); if ( fitted < scaled ) @@ -2239,43 +2246,47 @@ psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); } - } - glyph->do_horz_hints = 1; - glyph->do_vert_hints = 1; + glyph->do_horz_hints = 1; + glyph->do_vert_hints = 1; - glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD ); + glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); - glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || - hint_mode == FT_RENDER_MODE_LCD_V ); + glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); - glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); - for ( dimension = 0; dimension < 2; dimension++ ) - { - /* load outline coordinates into glyph */ - psh_glyph_load_points( glyph, dimension ); + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh_glyph_load_points( glyph, dimension ); - /* compute local extrema */ - psh_glyph_compute_extrema( glyph ); + /* compute local extrema */ + psh_glyph_compute_extrema( glyph ); - /* compute aligned stem/hints positions */ - psh_hint_table_align_hints( &glyph->hint_tables[dimension], - glyph->globals, - dimension, - glyph ); + /* compute aligned stem/hints positions */ + psh_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); - /* find strong points, align them, then interpolate others */ - psh_glyph_find_strong_points( glyph, dimension ); - if ( dimension == 1 ) - psh_glyph_find_blue_points( &globals->blues, glyph ); - psh_glyph_interpolate_strong_points( glyph, dimension ); - psh_glyph_interpolate_normal_points( glyph, dimension ); - psh_glyph_interpolate_other_points( glyph, dimension ); + /* find strong points, align them, then interpolate others */ + psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); + psh_glyph_interpolate_strong_points( glyph, dimension ); + psh_glyph_interpolate_normal_points( glyph, dimension ); + psh_glyph_interpolate_other_points( glyph, dimension ); - /* save hinted coordinates back to outline */ - psh_glyph_save_points( glyph, dimension ); + /* save hinted coordinates back to outline */ + psh_glyph_save_points( glyph, dimension ); + + if ( rescale ) + psh_globals_set_scale( glyph->globals, + old_x_scale, old_y_scale, 0, 0 ); + } } Exit: diff --git a/lib/3rdparty/freetype/src/pshinter/pshalgo.h b/lib/3rdparty/freetype/src/pshinter/pshalgo.h index f68de71202e..1a248a70524 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshalgo.h +++ b/lib/3rdparty/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,7 +32,7 @@ FT_BEGIN_HEADER typedef struct PSH_HintRec_* PSH_Hint; /* hint bit-flags */ - typedef enum + typedef enum PSH_Hint_Flags_ { PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, diff --git a/lib/3rdparty/freetype/src/pshinter/pshinter.c b/lib/3rdparty/freetype/src/pshinter/pshinter.c index 8e3f193093b..b35a2a91c53 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshinter.c +++ b/lib/3rdparty/freetype/src/pshinter/pshinter.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "pshpic.c" #include "pshrec.c" #include "pshglob.c" #include "pshalgo.c" diff --git a/lib/3rdparty/freetype/src/pshinter/pshmod.c b/lib/3rdparty/freetype/src/pshinter/pshmod.c index 4eb3d912729..91da5d7e6bc 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshmod.c +++ b/lib/3rdparty/freetype/src/pshinter/pshmod.c @@ -20,6 +20,7 @@ #include FT_INTERNAL_OBJECTS_H #include "pshrec.h" #include "pshalgo.h" +#include "pshpic.h" /* the Postscript Hinter module structure */ @@ -92,30 +93,26 @@ } - static - const PSHinter_Interface pshinter_interface = - { + FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface, pshinter_get_globals_funcs, pshinter_get_t1_funcs, pshinter_get_t2_funcs - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class pshinter_module_class = - { + FT_DEFINE_MODULE(pshinter_module_class, + 0, sizeof ( PS_Hinter_ModuleRec ), "pshinter", 0x10000L, 0x20000L, - &pshinter_interface, /* module-specific interface */ + &FTPSHINTER_INTERFACE_GET, /* module-specific interface */ (FT_Module_Constructor)ps_hinter_init, (FT_Module_Destructor) ps_hinter_done, (FT_Module_Requester) 0 /* no additional interface for now */ - }; - + ) /* END */ diff --git a/lib/3rdparty/freetype/src/pshinter/pshmod.h b/lib/3rdparty/freetype/src/pshinter/pshmod.h index 1a91025b260..0ae7e96f54e 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshmod.h +++ b/lib/3rdparty/freetype/src/pshinter/pshmod.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) pshinter_module_class; + FT_DECLARE_MODULE( pshinter_module_class ) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/pshinter/pshpic.c b/lib/3rdparty/freetype/src/pshinter/pshpic.c new file mode 100644 index 00000000000..51a08798883 --- /dev/null +++ b/lib/3rdparty/freetype/src/pshinter/pshpic.c @@ -0,0 +1,67 @@ +/***************************************************************************/ +/* */ +/* pshpic.c */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from pshmod.c */ + void FT_Init_Class_pshinter_interface( FT_Library, PSHinter_Interface*); + + void + pshinter_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->pshinter ) + { + FT_FREE( pic_container->pshinter ); + pic_container->pshinter = NULL; + } + } + + FT_Error + pshinter_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSHinterPIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->pshinter = container; + + /* add call to initialization function when you add new scripts */ + FT_Init_Class_pshinter_interface(library, &container->pshinter_interface); + +/*Exit:*/ + if(error) + pshinter_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* END */ diff --git a/lib/3rdparty/freetype/src/pshinter/pshpic.h b/lib/3rdparty/freetype/src/pshinter/pshpic.h new file mode 100644 index 00000000000..3555d8e8513 --- /dev/null +++ b/lib/3rdparty/freetype/src/pshinter/pshpic.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* pshpic.h */ +/* */ +/* The FreeType position independent code services for pshinter module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHPIC_H__ +#define __PSHPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC + +#define FTPSHINTER_INTERFACE_GET pshinter_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + typedef struct PSHinterPIC_ + { + PSHinter_Interface pshinter_interface; + } PSHinterPIC; + +#define GET_PIC(lib) ((PSHinterPIC*)((lib)->pic_container.autofit)) +#define FTPSHINTER_INTERFACE_GET (GET_PIC(library)->pshinter_interface) + + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSHPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/pshinter/pshrec.c b/lib/3rdparty/freetype/src/pshinter/pshrec.c index 2a885ef2763..0910cc5e6a5 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshrec.c +++ b/lib/3rdparty/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001, 2002, 2003, 2004, 2007 by */ +/* Copyright 2001, 2002, 2003, 2004, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,8 @@ #include FT_FREETYPE_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H + #include "pshrec.h" #include "pshalgo.h" @@ -62,7 +64,7 @@ { FT_UInt old_max = table->max_hints; FT_UInt new_max = count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -81,7 +83,7 @@ FT_Memory memory, PS_Hint *ahint ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count; PS_Hint hint = 0; @@ -137,7 +139,7 @@ { FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; FT_UInt new_max = ( count + 7 ) >> 3; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -184,7 +186,7 @@ FT_Int idx, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_Byte* p; @@ -234,7 +236,7 @@ { FT_UInt old_max = table->max_masks; FT_UInt new_max = count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( new_max > old_max ) @@ -254,7 +256,7 @@ PS_Mask *amask ) { FT_UInt count; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; PS_Mask mask = 0; @@ -285,7 +287,7 @@ FT_Memory memory, PS_Mask *amask ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count; PS_Mask mask; @@ -314,7 +316,7 @@ FT_UInt bit_count, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; PS_Mask mask; @@ -407,7 +409,7 @@ FT_Memory memory ) { FT_UInt temp; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; /* swap index1 and index2 so that index1 < index2 */ @@ -481,8 +483,8 @@ table->num_masks--; } else - FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", - index1, index2 )); + FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", + index1, index2 )); Exit: return error; @@ -497,7 +499,7 @@ FT_Memory memory ) { FT_Int index1, index2; - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) @@ -558,8 +560,8 @@ FT_UInt idx, FT_Memory memory ) { - PS_Mask mask; - FT_Error error = 0; + PS_Mask mask; + FT_Error error = PSH_Err_Ok; /* get last hint mask */ @@ -619,7 +621,7 @@ FT_UInt end_point, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; /* reset current mask, if any */ @@ -644,7 +646,7 @@ FT_Memory memory, FT_Int *aindex ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt flags = 0; @@ -715,7 +717,7 @@ FT_Int hint3, FT_Memory memory ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; FT_UInt count = dim->counters.num_masks; PS_Mask counter = dim->counters.masks; @@ -789,7 +791,7 @@ ps_dimension_done( &hints->dimension[0], memory ); ps_dimension_done( &hints->dimension[1], memory ); - hints->error = 0; + hints->error = PSH_Err_Ok; hints->memory = 0; } @@ -800,7 +802,7 @@ { FT_MEM_ZERO( hints, sizeof ( *hints ) ); hints->memory = memory; - return 0; + return PSH_Err_Ok; } @@ -813,7 +815,7 @@ { case PS_HINT_TYPE_1: case PS_HINT_TYPE_2: - hints->error = 0; + hints->error = PSH_Err_Ok; hints->hint_type = hint_type; ps_dimension_init( &hints->dimension[0] ); @@ -824,7 +826,7 @@ hints->error = PSH_Err_Invalid_Argument; hints->hint_type = hint_type; - FT_ERROR(( "ps_hints_open: invalid charstring type!\n" )); + FT_TRACE0(( "ps_hints_open: invalid charstring type\n" )); break; } } @@ -842,8 +844,8 @@ /* limit "dimension" to 0..1 */ if ( dimension < 0 || dimension > 1 ) { - FT_ERROR(( "ps_hints_stem: invalid dimension (%d) used\n", - dimension )); + FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); dimension = ( dimension != 0 ); } @@ -878,8 +880,8 @@ } default: - FT_ERROR(( "ps_hints_stem: called with invalid hint type (%d)\n", - hints->hint_type )); + FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n", + hints->hint_type )); break; } } @@ -888,11 +890,11 @@ /* add one Type1 counter stem to the current hints table */ static void - ps_hints_t1stem3( PS_Hints hints, - FT_Int dimension, - FT_Long* stems ) + ps_hints_t1stem3( PS_Hints hints, + FT_Int dimension, + FT_Fixed* stems ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( !hints->error ) @@ -906,8 +908,8 @@ /* limit "dimension" to 0..1 */ if ( dimension < 0 || dimension > 1 ) { - FT_ERROR(( "ps_hints_t1stem3: invalid dimension (%d) used\n", - dimension )); + FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n", + dimension )); dimension = ( dimension != 0 ); } @@ -919,9 +921,10 @@ /* add the three stems to our hints/masks table */ for ( count = 0; count < 3; count++, stems += 2 ) { - error = ps_dimension_add_t1stem( - dim, (FT_Int)stems[0], (FT_Int)stems[1], - memory, &idx[count] ); + error = ps_dimension_add_t1stem( dim, + (FT_Int)FIXED_TO_INT( stems[0] ), + (FT_Int)FIXED_TO_INT( stems[1] ), + memory, &idx[count] ); if ( error ) goto Fail; } @@ -934,7 +937,7 @@ } else { - FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" )); + FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" )); error = PSH_Err_Invalid_Argument; goto Fail; } @@ -953,7 +956,7 @@ ps_hints_t1reset( PS_Hints hints, FT_UInt end_point ) { - FT_Error error = 0; + FT_Error error = PSH_Err_Ok; if ( !hints->error ) @@ -1008,8 +1011,8 @@ /* check bit count; must be equal to current total hint count */ if ( bit_count != count1 + count2 ) { - FT_ERROR(( "ps_hints_t2mask: " - "called with invalid bitcount %d (instead of %d)\n", + FT_TRACE0(( "ps_hints_t2mask:" + " called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); /* simply ignore the operator */ @@ -1053,8 +1056,8 @@ /* check bit count, must be equal to current total hint count */ if ( bit_count != count1 + count2 ) { - FT_ERROR(( "ps_hints_t2counter: " - "called with invalid bitcount %d (instead of %d)\n", + FT_TRACE0(( "ps_hints_t2counter:" + " called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); /* simply ignore the operator */ @@ -1124,11 +1127,17 @@ } static void - t1_hints_stem( T1_Hints hints, - FT_Int dimension, - FT_Long* coords ) + t1_hints_stem( T1_Hints hints, + FT_Int dimension, + FT_Fixed* coords ) { - ps_hints_stem( (PS_Hints)hints, dimension, 1, coords ); + FT_Pos stems[2]; + + + stems[0] = FIXED_TO_INT( coords[0] ); + stems[1] = FIXED_TO_INT( coords[1] ); + + ps_hints_stem( (PS_Hints)hints, dimension, 1, stems ); } @@ -1183,7 +1192,7 @@ for ( n = 0; n < count * 2; n++ ) { y += coords[n]; - stems[n] = ( y + 0x8000L ) >> 16; + stems[n] = FIXED_TO_INT( y ); } /* compute lengths */ diff --git a/lib/3rdparty/freetype/src/pshinter/pshrec.h b/lib/3rdparty/freetype/src/pshinter/pshrec.h index f7ef9004ea1..dcb3197f94d 100644 --- a/lib/3rdparty/freetype/src/pshinter/pshrec.h +++ b/lib/3rdparty/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002, 2003, 2006 by */ +/* Copyright 2001, 2002, 2003, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ FT_BEGIN_HEADER typedef struct PS_HintRec_* PS_Hint; /* hint types */ - typedef enum + typedef enum PS_Hint_Type_ { PS_HINT_TYPE_1 = 1, PS_HINT_TYPE_2 = 2 @@ -61,7 +61,7 @@ FT_BEGIN_HEADER /* hint flags */ - typedef enum + typedef enum PS_Hint_Flags_ { PS_HINT_FLAG_GHOST = 1, PS_HINT_FLAG_BOTTOM = 2 diff --git a/lib/3rdparty/freetype/src/psnames/Jamfile b/lib/3rdparty/freetype/src/psnames/Jamfile index d85c1e97de4..06c0dda66f2 100644 --- a/lib/3rdparty/freetype/src/psnames/Jamfile +++ b/lib/3rdparty/freetype/src/psnames/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; if $(FT2_MULTI) { - _sources = psmodule ; + _sources = psmodule pspic ; } else { diff --git a/lib/3rdparty/freetype/src/psnames/module.mk b/lib/3rdparty/freetype/src/psnames/module.mk index a93063b928d..a6e908257cb 100644 --- a/lib/3rdparty/freetype/src/psnames/module.mk +++ b/lib/3rdparty/freetype/src/psnames/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += PSNAMES_MODULE define PSNAMES_MODULE -$(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, psnames_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/psnames/psmodule.c b/lib/3rdparty/freetype/src/psnames/psmodule.c index 8d8c476a145..35188504936 100644 --- a/lib/3rdparty/freetype/src/psnames/psmodule.c +++ b/lib/3rdparty/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,16 +24,17 @@ #include "pstables.h" #include "psnamerr.h" +#include "pspic.h" -#ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST #define VARIANT_BIT 0x80000000UL -#define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT ) +#define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) /* Return the Unicode value corresponding to a given glyph. Note that */ @@ -57,7 +58,7 @@ /* `uniXXXXYYYYZZZZ'... */ FT_Int count; - FT_ULong value = 0; + FT_UInt32 value = 0; const char* p = glyph_name + 3; @@ -92,7 +93,7 @@ if ( *p == '\0' ) return value; if ( *p == '.' ) - return value | VARIANT_BIT; + return (FT_UInt32)( value | VARIANT_BIT ); } } @@ -101,7 +102,7 @@ if ( glyph_name[0] == 'u' ) { FT_Int count; - FT_ULong value = 0; + FT_UInt32 value = 0; const char* p = glyph_name + 1; @@ -132,7 +133,7 @@ if ( *p == '\0' ) return value; if ( *p == '.' ) - return value | VARIANT_BIT; + return (FT_UInt32)( value | VARIANT_BIT ); } } @@ -154,9 +155,10 @@ /* now look up the glyph in the Adobe Glyph List */ if ( !dot ) - return ft_get_adobe_glyph_index( glyph_name, p ); + return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); else - return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT; + return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | + VARIANT_BIT ); } } @@ -174,9 +176,121 @@ /* sort base glyphs before glyph variants */ if ( unicode1 == unicode2 ) - return map1->unicode - map2->unicode; + { + if ( map1->unicode > map2->unicode ) + return 1; + else if ( map1->unicode < map2->unicode ) + return -1; + else + return 0; + } else - return unicode1 - unicode2; + { + if ( unicode1 > unicode2 ) + return 1; + else if ( unicode1 < unicode2 ) + return -1; + else + return 0; + } + } + + + /* support for extra glyphs not handled (well) in AGL; */ + /* we add extra mappings for them if necessary */ + +#define EXTRA_GLYPH_LIST_SIZE 10 + + static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = + { + /* WGL 4 */ + 0x0394, + 0x03A9, + 0x2215, + 0x00AD, + 0x02C9, + 0x03BC, + 0x2219, + 0x00A0, + /* Romanian */ + 0x021A, + 0x021B + }; + + static const char ft_extra_glyph_names[] = + { + 'D','e','l','t','a',0, + 'O','m','e','g','a',0, + 'f','r','a','c','t','i','o','n',0, + 'h','y','p','h','e','n',0, + 'm','a','c','r','o','n',0, + 'm','u',0, + 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, + 's','p','a','c','e',0, + 'T','c','o','m','m','a','a','c','c','e','n','t',0, + 't','c','o','m','m','a','a','c','c','e','n','t',0 + }; + + static const FT_Int + ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = + { + 0, + 6, + 12, + 21, + 28, + 35, + 38, + 53, + 59, + 72 + }; + + + static void + ps_check_extra_glyph_name( const char* gname, + FT_UInt glyph, + FT_UInt* extra_glyphs, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( ft_strcmp( ft_extra_glyph_names + + ft_extra_glyph_name_offsets[n], gname ) == 0 ) + { + if ( states[n] == 0 ) + { + /* mark this extra glyph as a candidate for the cmap */ + states[n] = 1; + extra_glyphs[n] = glyph; + } + + return; + } + } + } + + + static void + ps_check_extra_glyph_unicode( FT_UInt32 uni_char, + FT_UInt *states ) + { + FT_UInt n; + + + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( uni_char == ft_extra_glyph_unicodes[n] ) + { + /* disable this extra glyph from being added to the cmap */ + states[n] = 2; + + return; + } + } } @@ -191,12 +305,15 @@ { FT_Error error; + FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; + /* we first allocate the table */ table->num_maps = 0; table->maps = 0; - if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) ) + if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) { FT_UInt n; FT_UInt count; @@ -213,10 +330,14 @@ if ( gname ) { + ps_check_extra_glyph_name( gname, n, + extra_glyphs, extra_glyph_list_states ); uni_char = ps_unicode_value( gname ); if ( BASE_GLYPH( uni_char ) != 0 ) { + ps_check_extra_glyph_unicode( uni_char, + extra_glyph_list_states ); map->unicode = uni_char; map->glyph_index = n; map++; @@ -227,6 +348,19 @@ } } + for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) + { + if ( extra_glyph_list_states[n] == 1 ) + { + /* This glyph name has an additional representation. */ + /* Add it to the cmap. */ + + map->unicode = ft_extra_glyph_unicodes[n]; + map->glyph_index = extra_glyphs[n]; + map++; + } + } + /* now compress the table a bit */ count = (FT_UInt)( map - table->maps ); @@ -303,7 +437,7 @@ } - static FT_ULong + static FT_UInt32 ps_unicodes_char_next( PS_Unicodes table, FT_UInt32 *unicode ) { @@ -384,56 +518,66 @@ } - static - const FT_Service_PsCMapsRec pscmaps_interface = - { #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, (PS_Unicode_ValueFunc) ps_unicode_value, (PS_Unicodes_InitFunc) ps_unicodes_init, (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, -#else - - 0, - 0, - 0, - 0, - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - (PS_Macintosh_NameFunc) ps_get_macintosh_name, (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, t1_standard_encoding, t1_expert_encoding - }; + ) + +#else + + FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, + 0, + 0, + 0, + 0, + + (PS_Macintosh_NameFunc) ps_get_macintosh_name, + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding + ) + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + FT_DEFINE_SERVICEDESCREC1(pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET + ) - static const FT_ServiceDescRec pscmaps_services[] = - { - { FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface }, - { NULL, NULL } - }; static FT_Pointer psnames_get_service( FT_Module module, const char* service_id ) { - FT_UNUSED( module ); + FT_Library library = module->library; + FT_UNUSED(library); - return ft_service_list_lookup( pscmaps_services, service_id ); + return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id ); } -#endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ +#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES_SERVICE(a) 0 +#else +#define PUT_PS_NAMES_SERVICE(a) a +#endif - FT_CALLBACK_TABLE_DEF - const FT_Module_Class psnames_module_class = - { + FT_DEFINE_MODULE(psnames_module_class, + 0, /* this is not a font driver, nor a renderer */ sizeof ( FT_ModuleRec ), @@ -441,18 +585,12 @@ 0x10000L, /* driver version */ 0x20000L, /* driver requires FreeType 2 or above */ -#ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES - 0, + PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET), /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 -#else - (void*)&pscmaps_interface, /* module specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) psnames_get_service -#endif - }; + (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service) + ) + /* END */ diff --git a/lib/3rdparty/freetype/src/psnames/psmodule.h b/lib/3rdparty/freetype/src/psnames/psmodule.h index 232fdfb9a90..28fa14807c0 100644 --- a/lib/3rdparty/freetype/src/psnames/psmodule.h +++ b/lib/3rdparty/freetype/src/psnames/psmodule.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) psnames_module_class; + FT_DECLARE_MODULE( psnames_module_class ) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/psnames/psnames.c b/lib/3rdparty/freetype/src/psnames/psnames.c index d6ed998bfb1..1ede225dc9c 100644 --- a/lib/3rdparty/freetype/src/psnames/psnames.c +++ b/lib/3rdparty/freetype/src/psnames/psnames.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "pspic.c" #include "psmodule.c" diff --git a/lib/3rdparty/freetype/src/psnames/pspic.c b/lib/3rdparty/freetype/src/psnames/pspic.c new file mode 100644 index 00000000000..ed7dadda393 --- /dev/null +++ b/lib/3rdparty/freetype/src/psnames/pspic.c @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* pspic.c */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from psmodule.c */ + FT_Error FT_Create_Class_pscmaps_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_pscmaps_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_pscmaps_interface( FT_Library, FT_Service_PsCMapsRec*); + + void + psnames_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->psnames ) + { + PSModulePIC* container = (PSModulePIC*)pic_container->psnames; + if(container->pscmaps_services) + FT_Destroy_Class_pscmaps_services(library, container->pscmaps_services); + container->pscmaps_services = NULL; + FT_FREE( container ); + pic_container->psnames = NULL; + } + } + + FT_Error + psnames_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + PSModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->psnames = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services); + if(error) + goto Exit; + FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface); + +Exit: + if(error) + psnames_module_class_pic_free(library); + return error; + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/psnames/pspic.h b/lib/3rdparty/freetype/src/psnames/pspic.h new file mode 100644 index 00000000000..75a14fdcb9b --- /dev/null +++ b/lib/3rdparty/freetype/src/psnames/pspic.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* pspic.h */ +/* */ +/* The FreeType position independent code services for psnames module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSPIC_H__ +#define __PSPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_PSCMAPS_SERVICES_GET pscmaps_services +#define FT_PSCMAPS_INTERFACE_GET pscmaps_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + typedef struct PSModulePIC_ + { + FT_ServiceDescRec* pscmaps_services; + FT_Service_PsCMapsRec pscmaps_interface; + } PSModulePIC; + +#define GET_PIC(lib) ((PSModulePIC*)((lib)->pic_container.psnames)) +#define FT_PSCMAPS_SERVICES_GET (GET_PIC(library)->pscmaps_services) +#define FT_PSCMAPS_INTERFACE_GET (GET_PIC(library)->pscmaps_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __PSPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/psnames/pstables.h b/lib/3rdparty/freetype/src/psnames/pstables.h index cc40ef735d6..1521e9c2854 100644 --- a/lib/3rdparty/freetype/src/psnames/pstables.h +++ b/lib/3rdparty/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ /* */ /* PostScript glyph names. */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -561,7 +561,10 @@ * The lookup function to get the Unicode value for a given string * is defined below the table. */ - static const unsigned char ft_adobe_glyph_list[54791] = + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + static const unsigned char ft_adobe_glyph_list[54791L] = { 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, @@ -4086,5 +4089,7 @@ return 0; } +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + /* END */ diff --git a/lib/3rdparty/freetype/src/raster/Jamfile b/lib/3rdparty/freetype/src/raster/Jamfile index f6e4251cb8f..4f60e87c788 100644 --- a/lib/3rdparty/freetype/src/raster/Jamfile +++ b/lib/3rdparty/freetype/src/raster/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) raster ; if $(FT2_MULTI) { - _sources = ftraster ftrend1 ; + _sources = ftraster ftrend1 rastpic ; } else { diff --git a/lib/3rdparty/freetype/src/raster/ftmisc.h b/lib/3rdparty/freetype/src/raster/ftmisc.h index c5dbd50d003..f04b5404bb8 100644 --- a/lib/3rdparty/freetype/src/raster/ftmisc.h +++ b/lib/3rdparty/freetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ /* Miscellaneous macros for stand-alone rasterizer (specification */ /* only). */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -27,7 +27,8 @@ #ifndef __FTMISC_H__ #define __FTMISC_H__ -#include <string.h> /* memset */ + /* memset */ +#include FT_CONFIG_STANDARD_LIBRARY_H #define FT_BEGIN_HEADER #define FT_END_HEADER @@ -51,6 +52,31 @@ (FT_ULong)_x4 ) + /* from include/freetype2/ftsystem.h */ + + typedef struct FT_MemoryRec_* FT_Memory; + + typedef void* (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + typedef void (*FT_Free_Func)( FT_Memory memory, + void* block ); + + typedef void* (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + typedef struct FT_MemoryRec_ + { + void* user; + + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemoryRec; + /* from src/ftcalc.c */ #include <inttypes.h> diff --git a/lib/3rdparty/freetype/src/raster/ftraster.c b/lib/3rdparty/freetype/src/raster/ftraster.c index 4cfca4ed035..23ad592653c 100644 --- a/lib/3rdparty/freetype/src/raster/ftraster.c +++ b/lib/3rdparty/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,6 +49,10 @@ #ifdef _STANDALONE_ +#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> + +#include <string.h> /* for memset */ + #include "ftmisc.h" #include "ftimage.h" @@ -58,6 +62,8 @@ #include "ftraster.h" #include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ +#include "rastpic.h" + #endif /* !_STANDALONE_ */ @@ -72,13 +78,15 @@ /* profile is simply an array of scanline intersections on a given */ /* dimension. A profile's main attributes are */ /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ + /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ /* */ /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax'. */ + /* between `Ymin' and `Ymax' */ /* */ /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules. */ + /* `down', as this is very important for filling rules */ + /* */ + /* o its drop-out mode */ /* */ /* 2 - Sweeping the target map's scanlines in order to compute segment */ /* `spans' which are then filled. Additionally, this pass */ @@ -88,15 +96,15 @@ /* built from the bottom of the render pool, used as a stack. The */ /* following graphics shows the profile list under construction: */ /* */ - /* ____________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|___________________|_________|_________________|__ _ _ */ + /* __________________________________________________________ _ _ */ + /* | | | | | */ + /* | profile | coordinates for | profile | coordinates for |--> */ + /* | 1 | profile 1 | 2 | profile 2 |--> */ + /* |_________|_________________|_________|_________________|__ _ _ */ /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ + /* ^ ^ */ + /* | | */ + /* start of render pool top */ /* */ /* The top of the profile stack is kept in the `top' variable. */ /* */ @@ -140,13 +148,11 @@ /*************************************************************************/ /* define DEBUG_RASTER if you want to compile a debugging version */ -#define xxxDEBUG_RASTER +/* #define DEBUG_RASTER */ - /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ - /* 5-levels anti-aliasing */ -#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS -#define FT_RASTER_OPTION_ANTI_ALIASING -#endif + /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ + /* 5-levels anti-aliasing */ +/* #define FT_RASTER_OPTION_ANTI_ALIASING */ /* The size of the two-lines intermediate bitmap used */ /* for anti-aliasing, in bytes. */ @@ -183,13 +189,13 @@ /* Disable the tracing mechanism for simplicity -- developers can */ /* activate it easily by redefining these two macros. */ #ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ #endif #ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#define FT_TRACE1( x ) do ; while ( 0 ) /* nothing */ -#define FT_TRACE6( x ) do ; while ( 0 ) /* nothing */ +#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ #endif #define Raster_Err_None 0 @@ -199,9 +205,22 @@ #define Raster_Err_Invalid -4 #define Raster_Err_Unsupported -5 -#define ft_memset memset +#define ft_memset memset -#else /* _STANDALONE_ */ +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ + raster_reset_, raster_set_mode_, \ + raster_render_, raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; + +#else /* !_STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -217,7 +236,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* _STANDALONE_ */ +#endif /* !_STANDALONE_ */ #ifndef FT_MEM_SET @@ -306,13 +325,10 @@ } TPoint; - typedef enum TFlow_ - { - Flow_None = 0, - Flow_Up = 1, - Flow_Down = -1 - - } TFlow; + /* values for the `flags' bit field */ +#define Flow_Up 0x8 +#define Overshoot_Top 0x10 +#define Overshoot_Bottom 0x20 /* States of each line, arc, and profile */ @@ -331,18 +347,21 @@ struct TProfile_ { - FT_F26Dot6 X; /* current coordinate during sweep */ - PProfile link; /* link to next profile - various purpose */ - PLong offset; /* start of profile's data in render pool */ - int flow; /* Profile orientation: Asc/Descending */ - long height; /* profile's height in scanlines */ - long start; /* profile's starting scanline */ + FT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile (various purposes) */ + PLong offset; /* start of profile's data in render pool */ + unsigned flags; /* Bit 0-2: drop-out mode */ + /* Bit 3: profile orientation (up/down) */ + /* Bit 4: is top profile? */ + /* Bit 5: is bottom profile? */ + long height; /* profile's height in scanlines */ + long start; /* profile's starting scanline */ - unsigned countL; /* number of lines to step before this */ - /* profile becomes drawable */ + unsigned countL; /* number of lines to step before this */ + /* profile becomes drawable */ - PProfile next; /* next profile in same contour, used */ - /* during drop-out control */ + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ }; typedef PProfile TProfileList; @@ -372,10 +391,10 @@ #define RAS_VARS /* void */ #define RAS_VAR /* void */ -#define FT_UNUSED_RASTER do ; while ( 0 ) +#define FT_UNUSED_RASTER do { } while ( 0 ) -#else /* FT_STATIC_RASTER */ +#else /* !FT_STATIC_RASTER */ #define RAS_ARGS PWorker worker, @@ -387,10 +406,10 @@ #define FT_UNUSED_RASTER FT_UNUSED( worker ) -#endif /* FT_STATIC_RASTER */ +#endif /* !FT_STATIC_RASTER */ - typedef struct TWorker_ TWorker, *PWorker; + typedef struct TWorker_ TWorker, *PWorker; /* prototypes used for sweep function dispatch */ @@ -417,65 +436,68 @@ #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) #define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) - /* Note that I have moved the location of some fields in the */ - /* structure to ensure that the most used variables are used */ - /* at the top. Thus, their offset can be coded with less */ - /* opcodes, and it results in a smaller executable. */ +#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half ) +#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half ) + + /* The most used variables are positioned at the top of the structure. */ + /* Thus, their offset can be coded with less opcodes, resulting in a */ + /* smaller executable. */ struct TWorker_ { - Int precision_bits; /* precision related variables */ - Int precision; - Int precision_half; - Long precision_mask; - Int precision_shift; - Int precision_step; - Int precision_jitter; + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Long precision_mask; + Int precision_shift; + Int precision_step; + Int precision_jitter; - Int scale_shift; /* == precision_shift for bitmaps */ + Int scale_shift; /* == precision_shift for bitmaps */ /* == precision_shift+1 for pixmaps */ - PLong buff; /* The profiles buffer */ - PLong sizeBuff; /* Render pool size */ - PLong maxBuff; /* Profiles buffer size */ - PLong top; /* Current cursor in buffer */ + PLong buff; /* The profiles buffer */ + PLong sizeBuff; /* Render pool size */ + PLong maxBuff; /* Profiles buffer size */ + PLong top; /* Current cursor in buffer */ - FT_Error error; + FT_Error error; - Int numTurns; /* number of Y-turns in outline */ + Int numTurns; /* number of Y-turns in outline */ - TPoint* arc; /* current Bezier arc pointer */ + TPoint* arc; /* current Bezier arc pointer */ - UShort bWidth; /* target bitmap width */ - PByte bTarget; /* target bitmap buffer */ - PByte gTarget; /* target pixmap buffer */ + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ - Long lastX, lastY, minY, maxY; + Long lastX, lastY; + Long minY, maxY; - UShort num_Profs; /* current number of profiles */ + UShort num_Profs; /* current number of profiles */ - Bool fresh; /* signals a fresh new profile which */ - /* 'start' field must be completed */ - Bool joint; /* signals that the last arc ended */ + Bool fresh; /* signals a fresh new profile which */ + /* `start' field must be completed */ + Bool joint; /* signals that the last arc ended */ /* exactly on a scanline. Allows */ /* removal of doublets */ - PProfile cProfile; /* current profile */ - PProfile fProfile; /* head of linked list of profiles */ - PProfile gProfile; /* contour's first profile in case */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ /* of impact */ - TStates state; /* rendering state */ + TStates state; /* rendering state */ FT_Bitmap target; /* description of target bit/pixmap */ FT_Outline outline; - Long traceOfs; /* current offset in target bitmap */ - Long traceG; /* current offset in target pixmap */ + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ - Short traceIncr; /* sweep's increment in target bitmap */ + Short traceIncr; /* sweep's increment in target bitmap */ - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ /* dispatch variables */ @@ -484,31 +506,31 @@ Function_Sweep_Span* Proc_Sweep_Drop; Function_Sweep_Step* Proc_Sweep_Step; - Byte dropOutControl; /* current drop_out control method */ + Byte dropOutControl; /* current drop_out control method */ - Bool second_pass; /* indicates whether a horizontal pass */ + Bool second_pass; /* indicates whether a horizontal pass */ /* should be performed to control */ /* drop-out accurately when calling */ /* Render_Glyph. Note that there is */ /* no horizontal pass during gray */ /* rendering. */ - TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ - TBand band_stack[16]; /* band stack used for sub-banding */ - Int band_top; /* band stack top */ + TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ #ifdef FT_RASTER_OPTION_ANTI_ALIASING - Byte* grays; + Byte* grays; - Byte gray_lines[RASTER_GRAY_LINES]; + Byte gray_lines[RASTER_GRAY_LINES]; /* Intermediate table used to render the */ /* graylevels pixmaps. */ /* gray_lines is a buffer holding two */ /* monochrome scanlines */ - Short gray_width; /* width in bytes of one monochrome */ + Short gray_width; /* width in bytes of one monochrome */ /* intermediate scanline of gray_lines. */ /* Each gray pixel takes 2 bits long there */ @@ -520,47 +542,90 @@ }; - typedef struct TRaster_ + typedef struct TRaster_ { - char* buffer; - long buffer_size; - void* memory; - PWorker worker; - Byte grays[5]; - Short gray_width; + char* buffer; + long buffer_size; + void* memory; + PWorker worker; + Byte grays[5]; + Short gray_width; } TRaster, *PRaster; #ifdef FT_STATIC_RASTER - static TWorker cur_ras; + static TWorker cur_ras; #define ras cur_ras -#else +#else /* !FT_STATIC_RASTER */ #define ras (*worker) -#endif /* FT_STATIC_RASTER */ +#endif /* !FT_STATIC_RASTER */ -static const char count_table[256] = -{ - 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, - 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 }; +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /* A lookup table used to quickly count set bits in four gray 2x2 */ + /* cells. The values of the table have been produced with the */ + /* following code: */ + /* */ + /* for ( i = 0; i < 256; i++ ) */ + /* { */ + /* l = 0; */ + /* j = i; */ + /* */ + /* for ( c = 0; c < 4; c++ ) */ + /* { */ + /* l <<= 4; */ + /* */ + /* if ( j & 0x80 ) l++; */ + /* if ( j & 0x40 ) l++; */ + /* */ + /* j = ( j << 2 ) & 0xFF; */ + /* } */ + /* printf( "0x%04X", l ); */ + /* } */ + /* */ + + static const short count_table[256] = + { + 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, + 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, + 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, + 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, + 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, + 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, + 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, + 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, + 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, + 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, + 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, + 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, + 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, + 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 + }; + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ @@ -579,7 +644,7 @@ static const char count_table[256] = /* Set_High_Precision */ /* */ /* <Description> */ - /* Sets precision variables according to param flag. */ + /* Set precision variables according to param flag. */ /* */ /* <Input> */ /* High :: Set to True for high precision (typically for ppem < 18), */ @@ -590,9 +655,9 @@ static const char count_table[256] = { if ( High ) { - ras.precision_bits = 10; - ras.precision_step = 128; - ras.precision_jitter = 24; + ras.precision_bits = 12; + ras.precision_step = 256; + ras.precision_jitter = 50; } else { @@ -616,17 +681,21 @@ static const char count_table[256] = /* New_Profile */ /* */ /* <Description> */ - /* Creates a new profile in the render pool. */ + /* Create a new profile in the render pool. */ /* */ /* <Input> */ - /* aState :: The state/orientation of the new profile. */ + /* aState :: The state/orientation of the new profile. */ + /* */ + /* overshoot :: Whether the profile's unrounded start position */ + /* differs by at least a half pixel. */ /* */ /* <Return> */ /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ /* profile. */ /* */ static Bool - New_Profile( RAS_ARGS TStates aState ) + New_Profile( RAS_ARGS TStates aState, + Bool overshoot ) { if ( !ras.fProfile ) { @@ -641,29 +710,35 @@ static const char count_table[256] = return FAILURE; } - switch ( aState ) - { - case Ascending_State: - ras.cProfile->flow = Flow_Up; - FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); - break; - - case Descending_State: - ras.cProfile->flow = Flow_Down; - FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); - break; - - default: - FT_ERROR(( "New_Profile: invalid profile direction!\n" )); - ras.error = Raster_Err_Invalid; - return FAILURE; - } - + ras.cProfile->flags = 0; ras.cProfile->start = 0; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; ras.cProfile->link = (PProfile)0; ras.cProfile->next = (PProfile)0; + ras.cProfile->flags = ras.dropOutControl; + + switch ( aState ) + { + case Ascending_State: + ras.cProfile->flags |= Flow_Up; + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Bottom; + + FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); + break; + + case Descending_State: + if ( overshoot ) + ras.cProfile->flags |= Overshoot_Top; + FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); + break; + + default: + FT_ERROR(( "New_Profile: invalid profile direction\n" )); + ras.error = Raster_Err_Invalid; + return FAILURE; + } if ( !ras.gProfile ) ras.gProfile = ras.cProfile; @@ -682,13 +757,17 @@ static const char count_table[256] = /* End_Profile */ /* */ /* <Description> */ - /* Finalizes the current profile. */ + /* Finalize the current profile. */ + /* */ + /* <Input> */ + /* overshoot :: Whether the profile's unrounded end position differs */ + /* by at least a half pixel. */ /* */ /* <Return> */ /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ /* */ static Bool - End_Profile( RAS_ARG ) + End_Profile( RAS_ARGS Bool overshoot ) { Long h; PProfile oldProfile; @@ -698,7 +777,7 @@ static const char count_table[256] = if ( h < 0 ) { - FT_ERROR(( "End_Profile: negative height encountered!\n" )); + FT_ERROR(( "End_Profile: negative height encountered\n" )); ras.error = Raster_Err_Neg_Height; return FAILURE; } @@ -708,15 +787,24 @@ static const char count_table[256] = FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", (long)ras.cProfile, ras.cProfile->start, h )); - oldProfile = ras.cProfile; ras.cProfile->height = h; - ras.cProfile = (PProfile)ras.top; + if ( overshoot ) + { + if ( ras.cProfile->flags & Flow_Up ) + ras.cProfile->flags |= Overshoot_Top; + else + ras.cProfile->flags |= Overshoot_Bottom; + } - ras.top += AlignProfileSize; + oldProfile = ras.cProfile; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; - oldProfile->next = ras.cProfile; + + oldProfile->next = ras.cProfile; ras.num_Profs++; } @@ -739,7 +827,7 @@ static const char count_table[256] = /* Insert_Y_Turn */ /* */ /* <Description> */ - /* Inserts a salient into the sorted list placed on top of the render */ + /* Insert a salient into the sorted list placed on top of the render */ /* pool. */ /* */ /* <Input> */ @@ -794,7 +882,7 @@ static const char count_table[256] = /* Finalize_Profile_Table */ /* */ /* <Description> */ - /* Adjusts all links in the profiles list. */ + /* Adjust all links in the profiles list. */ /* */ /* <Return> */ /* SUCCESS on success. FAILURE in case of overflow. */ @@ -808,10 +896,10 @@ static const char count_table[256] = n = ras.num_Profs; + p = ras.fProfile; - if ( n > 1 ) + if ( n > 1 && p ) { - p = ras.fProfile; while ( n > 0 ) { if ( n > 1 ) @@ -819,23 +907,21 @@ static const char count_table[256] = else p->link = NULL; - switch ( p->flow ) + if ( p->flags & Flow_Up ) + { + bottom = (Int)p->start; + top = (Int)( p->start + p->height - 1 ); + } + else { - case Flow_Down: bottom = (Int)( p->start - p->height + 1 ); top = (Int)p->start; p->start = bottom; p->offset += p->height - 1; - break; - - case Flow_Up: - default: - bottom = (Int)p->start; - top = (Int)( p->start + p->height - 1 ); } - if ( Insert_Y_Turn( RAS_VARS bottom ) || - Insert_Y_Turn( RAS_VARS top + 1 ) ) + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top + 1 ) ) return FAILURE; p = p->link; @@ -855,7 +941,7 @@ static const char count_table[256] = /* Split_Conic */ /* */ /* <Description> */ - /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */ + /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ /* stack. */ /* */ /* <Input> */ @@ -894,7 +980,7 @@ static const char count_table[256] = /* Split_Cubic */ /* */ /* <Description> */ - /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */ + /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ /* Bezier stack. */ /* */ /* <Note> */ @@ -936,7 +1022,7 @@ static const char count_table[256] = /* Line_Up */ /* */ /* <Description> */ - /* Computes the x-coordinates of an ascending line segment and stores */ + /* Compute the x-coordinates of an ascending line segment and store */ /* them in the render pool. */ /* */ /* <Input> */ @@ -1075,8 +1161,8 @@ static const char count_table[256] = /* Line_Down */ /* */ /* <Description> */ - /* Computes the x-coordinates of an descending line segment and */ - /* stores them in the render pool. */ + /* Compute the x-coordinates of an descending line segment and store */ + /* them in the render pool. */ /* */ /* <Input> */ /* x1 :: The x-coordinate of the segment's start point. */ @@ -1126,7 +1212,7 @@ static const char count_table[256] = /* Bezier_Up */ /* */ /* <Description> */ - /* Computes the x-coordinates of an ascending Bezier arc and stores */ + /* Compute the x-coordinates of an ascending Bezier arc and store */ /* them in the render pool. */ /* */ /* <Input> */ @@ -1227,7 +1313,7 @@ static const char count_table[256] = } else { - *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, + *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, e - y1, y2 - y1 ); arc -= degree; e += ras.precision; @@ -1259,7 +1345,7 @@ static const char count_table[256] = /* Bezier_Down */ /* */ /* <Description> */ - /* Computes the x-coordinates of an descending Bezier arc and stores */ + /* Compute the x-coordinates of an descending Bezier arc and store */ /* them in the render pool. */ /* */ /* <Input> */ @@ -1308,7 +1394,7 @@ static const char count_table[256] = /* Line_To */ /* */ /* <Description> */ - /* Injects a new line segment and adjusts Profiles list. */ + /* Inject a new line segment and adjust the Profiles list. */ /* */ /* <Input> */ /* x :: The x-coordinate of the segment's end point (its start point */ @@ -1332,13 +1418,15 @@ static const char count_table[256] = case Unknown_State: if ( y > ras.lastY ) { - if ( New_Profile( RAS_VARS Ascending_State ) ) + if ( New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } else { if ( y < ras.lastY ) - if ( New_Profile( RAS_VARS Descending_State ) ) + if ( New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1346,8 +1434,9 @@ static const char count_table[256] = case Ascending_State: if ( y < ras.lastY ) { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Descending_State ) ) + if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Descending_State, + IS_TOP_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1355,8 +1444,9 @@ static const char count_table[256] = case Descending_State: if ( y > ras.lastY ) { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Ascending_State ) ) + if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || + New_Profile( RAS_VARS Ascending_State, + IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) return FAILURE; } break; @@ -1371,13 +1461,13 @@ static const char count_table[256] = { case Ascending_State: if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) + x, y, ras.minY, ras.maxY ) ) return FAILURE; break; case Descending_State: if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) + x, y, ras.minY, ras.maxY ) ) return FAILURE; break; @@ -1398,7 +1488,7 @@ static const char count_table[256] = /* Conic_To */ /* */ /* <Description> */ - /* Injects a new conic arc and adjusts the profile list. */ + /* Inject a new conic arc and adjust the profile list. */ /* */ /* <Input> */ /* cx :: The x-coordinate of the arc's new control point. */ @@ -1428,8 +1518,10 @@ static const char count_table[256] = ras.arc = ras.arcs; ras.arc[2].x = ras.lastX; ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; ras.arc[1].y = cy; - ras.arc[0].x = x; ras.arc[0].y = y; + ras.arc[1].x = cx; + ras.arc[1].y = cy; + ras.arc[0].x = x; + ras.arc[0].y = y; do { @@ -1469,13 +1561,17 @@ static const char count_table[256] = state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + /* finalize current profile if any */ - if ( ras.state != Unknown_State && - End_Profile( RAS_VAR ) ) + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) goto Fail; /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez ) ) + if ( New_Profile( RAS_VARS state_bez, o ) ) goto Fail; } @@ -1508,7 +1604,7 @@ static const char count_table[256] = /* Cubic_To */ /* */ /* <Description> */ - /* Injects a new cubic arc and adjusts the profile list. */ + /* Inject a new cubic arc and adjust the profile list. */ /* */ /* <Input> */ /* cx1 :: The x-coordinate of the arc's first new control point. */ @@ -1544,9 +1640,12 @@ static const char count_table[256] = ras.arc = ras.arcs; ras.arc[3].x = ras.lastX; ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; ras.arc[2].y = cy1; - ras.arc[1].x = cx2; ras.arc[1].y = cy2; - ras.arc[0].x = x; ras.arc[0].y = y; + ras.arc[2].x = cx1; + ras.arc[2].y = cy1; + ras.arc[1].x = cx2; + ras.arc[1].y = cy2; + ras.arc[0].x = x; + ras.arc[0].y = y; do { @@ -1598,11 +1697,16 @@ static const char count_table[256] = /* detect a change of direction */ if ( ras.state != state_bez ) { - if ( ras.state != Unknown_State && - End_Profile( RAS_VAR ) ) + Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); + + + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VARS o ) ) goto Fail; - if ( New_Profile( RAS_VARS state_bez ) ) + if ( New_Profile( RAS_VARS state_bez, o ) ) goto Fail; } @@ -1646,7 +1750,7 @@ static const char count_table[256] = /* Decompose_Curve */ /* */ /* <Description> */ - /* Scans the outline arrays in order to emit individual segments and */ + /* Scan the outline arrays in order to emit individual segments and */ /* Beziers by calling Line_To() and Bezier_To(). It handles all */ /* weird cases, like when the first point is off the curve, or when */ /* there are simply no `on' points in the contour! */ @@ -1695,8 +1799,13 @@ static const char count_table[256] = v_control = v_start; point = points + first; - tags = ras.outline.tags + first; - tag = FT_CURVE_TAG( tags[0] ); + tags = ras.outline.tags + first; + + /* set scan mode if necessary */ + if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) + ras.dropOutControl = (Byte)tags[0] >> 5; + + tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ if ( tag == FT_CURVE_TAG_CUBIC ) @@ -1867,7 +1976,7 @@ static const char count_table[256] = /* Convert_Glyph */ /* */ /* <Description> */ - /* Converts a glyph into a series of segments and arcs and makes a */ + /* Convert a glyph into a series of segments and arcs and make a */ /* profiles list with them. */ /* */ /* <Input> */ @@ -1902,27 +2011,36 @@ static const char count_table[256] = for ( i = 0; i < ras.outline.n_contours; i++ ) { + Bool o; + + ras.state = Unknown_State; ras.gProfile = NULL; if ( Decompose_Curve( RAS_VARS (unsigned short)start, - ras.outline.contours[i], - flipped ) ) + ras.outline.contours[i], + flipped ) ) return FAILURE; start = ras.outline.contours[i] + 1; - /* We must now see whether the extreme arcs join or not */ + /* we must now check whether the extreme arcs join or not */ if ( FRAC( ras.lastY ) == 0 && ras.lastY >= ras.minY && ras.lastY <= ras.maxY ) - if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) + if ( ras.gProfile && + ( ras.gProfile->flags & Flow_Up ) == + ( ras.cProfile->flags & Flow_Up ) ) ras.top--; /* Note that ras.gProfile can be nil if the contour was too small */ /* to be drawn. */ lastProfile = ras.cProfile; - if ( End_Profile( RAS_VAR ) ) + if ( ras.cProfile->flags & Flow_Up ) + o = IS_TOP_OVERSHOOT( ras.lastY ); + else + o = IS_BOTTOM_OVERSHOOT( ras.lastY ); + if ( End_Profile( RAS_VARS o ) ) return FAILURE; /* close the `next profile in contour' linked list */ @@ -2042,7 +2160,7 @@ static const char count_table[256] = while ( current ) { current->X = *current->offset; - current->offset += current->flow; + current->offset += current->flags & Flow_Up ? 1 : -1; current->height--; current = current->link; } @@ -2148,8 +2266,10 @@ static const char count_table[256] = f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); - if ( ras.gray_min_x > c1 ) ras.gray_min_x = (short)c1; - if ( ras.gray_max_x < c2 ) ras.gray_max_x = (short)c2; + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = (short)c1; + if ( ras.gray_max_x < c2 ) + ras.gray_max_x = (short)c2; target = ras.bTarget + ras.traceOfs + c1; c2 -= c1; @@ -2182,38 +2302,63 @@ static const char count_table[256] = PProfile left, PProfile right ) { - Long e1, e2; + Long e1, e2, pxl; Short c1, f1; /* Drop-out control */ - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); + /* e2 x2 x1 e1 */ + /* */ + /* ^ | */ + /* | | */ + /* +-------------+---------------------+------------+ */ + /* | | */ + /* | v */ + /* */ + /* pixel contour contour pixel */ + /* center center */ + + /* drop-out mode scan conversion rules (as defined in OpenType) */ + /* --------------------------------------------------------------- */ + /* 0 1, 2, 3 */ + /* 1 1, 2, 4 */ + /* 2 1, 2 */ + /* 3 same as mode 2 */ + /* 4 1, 2, 5 */ + /* 5 1, 2, 6 */ + /* 6, 7 same as mode 2 */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { - case 1: - e1 = e2; + case 0: /* simple drop-outs including stubs */ + pxl = e2; break; - case 4: - e1 = CEILING( (x1 + x2 + 1) / 2 ); + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - case 2: - case 5: - /* Drop-out Control Rule #4 */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ + /* Drop-out Control Rules #4 and #6 */ + + /* The specification neither provides an exact definition */ + /* of a `stub' nor gives exact rules to exclude them. */ /* */ - /* Here, we only get rid of stubs recognized if: */ + /* Here the constraints we use to recognize a stub. */ /* */ /* upper stub: */ /* */ @@ -2227,59 +2372,64 @@ static const char count_table[256] = /* - P_Left is the successor of P_Right in that contour */ /* - y is the bottom of P_Left */ /* */ + /* We draw a stub if the following constraints are met. */ + /* */ + /* - for an upper or lower stub, there is top or bottom */ + /* overshoot, respectively */ + /* - the covered interval is greater or equal to a half */ + /* pixel */ - /* FIXXXME: uncommenting this line solves the disappearing */ - /* bit problem in the `7' of verdana 10pts, but */ - /* makes a new one in the `C' of arial 14pts */ - -#if 0 - if ( x2 - x1 < ras.precision_half ) -#endif - { - /* upper stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* lower stub test */ - if ( right->next == left && left->start == y ) - return; - } - - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); - - c1 = (Short)( e1 >> 3 ); - f1 = (Short)( e1 & 7 ); - - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + /* upper stub test */ + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) return; - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + /* lower stub test */ + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) + return; + if ( dropOutControl == 1 ) + pxl = e2; + else + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - default: - return; /* unsupported mode */ + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ } + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + c1 = (Short)( e1 >> 3 ); + f1 = (Short)( e1 & 7 ); + + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) + return; } else return; } - e1 = TRUNC( e1 ); + e1 = TRUNC( pxl ); if ( e1 >= 0 && e1 < ras.bWidth ) { c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); - if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; - if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1; + if ( ras.gray_min_x > c1 ) + ras.gray_min_x = c1; + if ( ras.gray_max_x < c1 ) + ras.gray_max_x = c1; ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } @@ -2363,74 +2513,88 @@ static const char count_table[256] = PProfile left, PProfile right ) { - Long e1, e2; + Long e1, e2, pxl; PByte bits; Byte f1; /* During the horizontal sweep, we only take care of drop-outs */ - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); + /* e1 + <-- pixel center */ + /* | */ + /* x1 ---+--> <-- contour */ + /* | */ + /* | */ + /* x2 <--+--- <-- contour */ + /* | */ + /* | */ + /* e2 + <-- pixel center */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + pxl = e1; if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { - case 1: - e1 = e2; + case 0: /* simple drop-outs including stubs */ + pxl = e2; break; - case 4: - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + case 4: /* smart drop-outs including stubs */ + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - case 2: - case 5: - - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) + if ( left->next == right && + left->height <= 0 && + !( left->flags & Overshoot_Top && + x2 - x1 >= ras.precision_half ) ) return; /* leftmost stub test */ - if ( right->next == left && left->start == y ) + if ( right->next == left && + left->start == y && + !( left->flags & Overshoot_Bottom && + x2 - x1 >= ras.precision_half ) ) return; - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; - - if ( ras.dropOutControl == 2 ) - e1 = e2; + if ( dropOutControl == 1 ) + pxl = e2; else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - + pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - default: - return; /* unsupported mode */ + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ } + + /* check that the other pixel isn't set */ + e1 = pxl == e1 ? e2 : e1; + + e1 = TRUNC( e1 ); + + bits = ras.bTarget + ( y >> 3 ); + f1 = (Byte)( 0x80 >> ( y & 7 ) ); + + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; } else return; @@ -2439,7 +2603,7 @@ static const char count_table[256] = bits = ras.bTarget + ( y >> 3 ); f1 = (Byte)( 0x80 >> ( y & 7 ) ); - e1 = TRUNC( e1 ); + e1 = TRUNC( pxl ); if ( e1 >= 0 && e1 < ras.target.rows ) { @@ -2509,10 +2673,10 @@ static const char count_table[256] = static void Vertical_Gray_Sweep_Step( RAS_ARG ) { - Int c1, c2; - PByte pix, bit, bit2; - char* count = (char*)count_table; - Byte* grays; + Int c1, c2; + PByte pix, bit, bit2; + short* count = (short*)count_table; + Byte* grays; ras.traceOfs += ras.gray_width; @@ -2524,10 +2688,10 @@ static const char count_table[256] = if ( ras.gray_max_x >= 0 ) { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; + Long last_pixel = ras.target.width - 1; + Int last_cell = last_pixel >> 2; + Int last_bit = last_pixel & 3; + Bool over = 0; if ( ras.gray_max_x >= last_cell && last_bit != 3 ) @@ -2539,8 +2703,8 @@ static const char count_table[256] = if ( ras.gray_min_x < 0 ) ras.gray_min_x = 0; - bit = ras.bTarget + ras.gray_min_x; - bit2 = bit + ras.gray_width; + bit = ras.bTarget + ras.gray_min_x; + bit2 = bit + ras.gray_width; c1 = ras.gray_max_x - ras.gray_min_x; @@ -2625,32 +2789,30 @@ static const char count_table[256] = /* During the horizontal sweep, we only take care of drop-outs */ + e1 = CEILING( x1 ); e2 = FLOOR ( x2 ); if ( e1 > e2 ) { + Int dropOutControl = left->flags & 7; + + if ( e1 == e2 + ras.precision ) { - switch ( ras.dropOutControl ) + switch ( dropOutControl ) { - case 1: + case 0: /* simple drop-outs including stubs */ e1 = e2; break; - case 4: - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + case 4: /* smart drop-outs including stubs */ + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - case 2: - case 5: - - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ + case 1: /* simple drop-outs excluding stubs */ + case 5: /* smart drop-outs excluding stubs */ + /* see Vertical_Sweep_Drop for details */ /* rightmost stub test */ if ( left->next == right && left->height <= 0 ) @@ -2660,15 +2822,15 @@ static const char count_table[256] = if ( right->next == left && left->start == y ) return; - if ( ras.dropOutControl == 2 ) + if ( dropOutControl == 1 ) e1 = e2; else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); + e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); break; - default: - return; /* unsupported mode */ + default: /* modes 2, 3, 6, 7 */ + return; /* no drop-out control */ } } else @@ -2720,7 +2882,7 @@ static const char count_table[256] = TProfileList draw_left, draw_right; - /* Init empty linked lists */ + /* initialize empty linked lists */ Init_Linked( &waiting ); @@ -2740,8 +2902,10 @@ static const char count_table[256] = bottom = (Short)P->start; top = (Short)( P->start + P->height - 1 ); - if ( min_Y > bottom ) min_Y = bottom; - if ( max_Y < top ) max_Y = top; + if ( min_Y > bottom ) + min_Y = bottom; + if ( max_Y < top ) + max_Y = top; P->X = 0; InsNew( &waiting, P ); @@ -2749,18 +2913,18 @@ static const char count_table[256] = P = Q; } - /* Check the Y-turns */ + /* check the Y-turns */ if ( ras.numTurns == 0 ) { ras.error = Raster_Err_Invalid; return FAILURE; } - /* Now inits the sweep */ + /* now initialize the sweep */ ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); - /* Then compute the distance of each profile from min_Y */ + /* then compute the distance of each profile from min_Y */ P = waiting; @@ -2770,18 +2934,18 @@ static const char count_table[256] = P = P->link; } - /* Let's go */ + /* let's go */ y = min_Y; y_height = 0; - if ( ras.numTurns > 0 && + if ( ras.numTurns > 0 && ras.sizeBuff[-ras.numTurns] == min_Y ) ras.numTurns--; while ( ras.numTurns > 0 ) { - /* look in the waiting list for new activations */ + /* check waiting list for new activations */ P = waiting; @@ -2793,22 +2957,16 @@ static const char count_table[256] = { DelOld( &waiting, P ); - switch ( P->flow ) - { - case Flow_Up: + if ( P->flags & Flow_Up ) InsNew( &draw_left, P ); - break; - - case Flow_Down: + else InsNew( &draw_right, P ); - break; - } } P = Q; } - /* Sort the drawing lists */ + /* sort the drawing lists */ Sort( &draw_left ); Sort( &draw_right ); @@ -2818,7 +2976,7 @@ static const char count_table[256] = while ( y < y_change ) { - /* Let's trace */ + /* let's trace */ dropouts = 0; @@ -2837,22 +2995,28 @@ static const char count_table[256] = x2 = xs; } - if ( x2 - x1 <= ras.precision ) + e1 = FLOOR( x1 ); + e2 = CEILING( x2 ); + + if ( x2 - x1 <= ras.precision && + e1 != x1 && e2 != x2 ) { - e1 = FLOOR( x1 ); - e2 = CEILING( x2 ); - - if ( ras.dropOutControl != 0 && - ( e1 > e2 || e2 == e1 + ras.precision ) ) + if ( e1 > e2 || e2 == e1 + ras.precision ) { - /* a drop out was detected */ + Int dropOutControl = P_Left->flags & 7; - P_Left ->X = x1; - P_Right->X = x2; - /* mark profile for drop-out processing */ - P_Left->countL = 1; - dropouts++; + if ( dropOutControl != 2 ) + { + /* a drop-out was detected */ + + P_Left ->X = x1; + P_Right->X = x2; + + /* mark profile for drop-out processing */ + P_Left->countL = 1; + dropouts++; + } goto Skip_To_Next; } @@ -2866,9 +3030,9 @@ static const char count_table[256] = P_Right = P_Right->link; } - /* now perform the dropouts _after_ the span drawing -- */ - /* drop-outs processing has been moved out of the loop */ - /* for performance tuning */ + /* handle drop-outs _after_ the span drawing -- */ + /* drop-out processing has been moved out of the loop */ + /* for performance tuning */ if ( dropouts > 0 ) goto Scan_DropOuts; @@ -2885,7 +3049,7 @@ static const char count_table[256] = } } - /* Now finalize the profiles that needs it */ + /* now finalize the profiles that need it */ P = draw_left; while ( P ) @@ -2906,7 +3070,7 @@ static const char count_table[256] = } } - /* for gray-scaling, flushes the bitmap scanline cache */ + /* for gray-scaling, flush the bitmap scanline cache */ while ( y <= max_Y ) { ras.Proc_Sweep_Step( RAS_VAR ); @@ -2949,7 +3113,7 @@ static const char count_table[256] = /* Render_Single_Pass */ /* */ /* <Description> */ - /* Performs one sweep with sub-banding. */ + /* Perform one sweep with sub-banding. */ /* */ /* <Input> */ /* flipped :: If set, flip the direction of the outline. */ @@ -3024,7 +3188,7 @@ static const char count_table[256] = /* Render_Glyph */ /* */ /* <Description> */ - /* Renders a glyph in a bitmap. Sub-banding if needed. */ + /* Render a glyph in a bitmap. Sub-banding if needed. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -3036,14 +3200,24 @@ static const char count_table[256] = Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift; - /* Drop-out mode 2 is hard-coded since this is the only mode used */ - /* on Windows platforms. Using other modes, as specified by the */ - /* font, results in misplaced pixels. */ - ras.dropOutControl = 2; - ras.second_pass = (FT_Byte)( !( ras.outline.flags & - FT_OUTLINE_SINGLE_PASS ) ); + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = (FT_Byte)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_PASS ) ); /* Vertical Sweep */ ras.Proc_Sweep_Init = Vertical_Sweep_Init; @@ -3062,7 +3236,7 @@ static const char count_table[256] = return error; /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 0 ) + if ( ras.second_pass && ras.dropOutControl != 2 ) { ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Sweep_Span; @@ -3083,14 +3257,13 @@ static const char count_table[256] = #ifdef FT_RASTER_OPTION_ANTI_ALIASING - /*************************************************************************/ /* */ /* <Function> */ /* Render_Gray_Glyph */ /* */ /* <Description> */ - /* Renders a glyph with grayscaling. Sub-banding if needed. */ + /* Render a glyph with grayscaling. Sub-banding if needed. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -3103,13 +3276,23 @@ static const char count_table[256] = Set_High_Precision( RAS_VARS ras.outline.flags & - FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift + 1; - /* Drop-out mode 2 is hard-coded since this is the only mode used */ - /* on Windows platforms. Using other modes, as specified by the */ - /* font, results in misplaced pixels. */ - ras.dropOutControl = 2; - ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift + 1; + + if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) + ras.dropOutControl = 2; + else + { + if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) + ras.dropOutControl = 4; + else + ras.dropOutControl = 0; + + if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) + ras.dropOutControl += 1; + } + + ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); /* Vertical Sweep */ @@ -3137,7 +3320,7 @@ static const char count_table[256] = return error; /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 0 ) + if ( ras.second_pass && ras.dropOutControl != 2 ) { ras.Proc_Sweep_Init = Horizontal_Sweep_Init; ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; @@ -3172,8 +3355,6 @@ static const char count_table[256] = static void ft_black_init( PRaster raster ) { - FT_UNUSED( raster ); - #ifdef FT_RASTER_OPTION_ANTI_ALIASING FT_UInt n; @@ -3183,7 +3364,8 @@ static const char count_table[256] = raster->grays[n] = n * 255 / 4; raster->gray_width = RASTER_GRAY_LINES / 2; - +#else + FT_UNUSED( raster ); #endif } @@ -3196,7 +3378,7 @@ static const char count_table[256] = static int - ft_black_new( void* memory, + ft_black_new( void* memory, FT_Raster *araster ) { static TRaster the_raster; @@ -3254,9 +3436,9 @@ static const char count_table[256] = static void - ft_black_reset( PRaster raster, - char* pool_base, - long pool_size ) + ft_black_reset( PRaster raster, + char* pool_base, + long pool_size ) { if ( raster ) { @@ -3281,9 +3463,9 @@ static const char count_table[256] = static void - ft_black_set_mode( PRaster raster, - unsigned long mode, - const char* palette ) + ft_black_set_mode( PRaster raster, + unsigned long mode, + const char* palette ) { #ifdef FT_RASTER_OPTION_ANTI_ALIASING @@ -3319,14 +3501,18 @@ static const char count_table[256] = if ( !raster || !raster->buffer || !raster->buffer_size ) return Raster_Err_Not_Ini; + if ( !outline ) + return Raster_Err_Invalid; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return Raster_Err_None; - if ( !outline || !outline->contours || !outline->points ) + if ( !outline->contours || !outline->points ) return Raster_Err_Invalid; - if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) return Raster_Err_Invalid; worker = raster->worker; @@ -3335,35 +3521,43 @@ static const char count_table[256] = if ( params->flags & FT_RASTER_FLAG_DIRECT ) return Raster_Err_Unsupported; - if ( !target_map || !target_map->buffer ) + if ( !target_map ) return Raster_Err_Invalid; - ras.outline = *outline; - ras.target = *target_map; + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return Raster_Err_None; - worker->buff = (PLong) raster->buffer; - worker->sizeBuff = worker->buff + - raster->buffer_size / sizeof ( Long ); + if ( !target_map->buffer ) + return Raster_Err_Invalid; + + ras.outline = *outline; + ras.target = *target_map; + + worker->buff = (PLong) raster->buffer; + worker->sizeBuff = worker->buff + + raster->buffer_size / sizeof ( Long ); #ifdef FT_RASTER_OPTION_ANTI_ALIASING - worker->grays = raster->grays; - worker->gray_width = raster->gray_width; + worker->grays = raster->grays; + worker->gray_width = raster->gray_width; + + FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); #endif - return ( ( params->flags & FT_RASTER_FLAG_AA ) - ? Render_Gray_Glyph( RAS_VAR ) - : Render_Glyph( RAS_VAR ) ); + return ( params->flags & FT_RASTER_FLAG_AA ) + ? Render_Gray_Glyph( RAS_VAR ) + : Render_Glyph( RAS_VAR ); } - const FT_Raster_Funcs ft_standard_raster = - { + FT_DEFINE_RASTER_FUNCS( ft_standard_raster, FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) ft_black_new, (FT_Raster_Reset_Func) ft_black_reset, (FT_Raster_Set_Mode_Func)ft_black_set_mode, (FT_Raster_Render_Func) ft_black_render, (FT_Raster_Done_Func) ft_black_done - }; + ) /* END */ diff --git a/lib/3rdparty/freetype/src/raster/ftrend1.c b/lib/3rdparty/freetype/src/raster/ftrend1.c index 3cc8d07413b..1ed8af61217 100644 --- a/lib/3rdparty/freetype/src/raster/ftrend1.c +++ b/lib/3rdparty/freetype/src/raster/ftrend1.c @@ -21,6 +21,7 @@ #include FT_OUTLINE_H #include "ftrend1.h" #include "ftraster.h" +#include "rastpic.h" #include "rasterrs.h" @@ -118,6 +119,7 @@ } /* check rendering mode */ +#ifndef FT_CONFIG_OPTION_PIC if ( mode != FT_RENDER_MODE_MONO ) { /* raster1 is only capable of producing monochrome bitmaps */ @@ -130,6 +132,25 @@ if ( render->clazz == &ft_raster5_renderer_class ) return Raster_Err_Cannot_Render_Glyph; } +#else /* FT_CONFIG_OPTION_PIC */ + /* When PIC is enabled, we cannot get to the class object */ + /* so instead we check the final character in the class name */ + /* ("raster5" or "raster1"). Yes this is a hack. */ + /* The "correct" thing to do is have different render function */ + /* for each of the classes. */ + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz->root.module_name[6] == '1' ) + return Raster_Err_Cannot_Render_Glyph; + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz->root.module_name[6] == '5' ) + return Raster_Err_Cannot_Render_Glyph; + } +#endif /* FT_CONFIG_OPTION_PIC */ outline = &slot->outline; @@ -208,10 +229,8 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_raster1_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_raster1_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -224,7 +243,7 @@ (FT_Module_Constructor)ft_raster1_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -233,18 +252,17 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - (FT_Raster_Funcs*) &ft_standard_raster - }; + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) /* This renderer is _NOT_ part of the default modules; you will need */ /* to register it by hand in your application. It should only be */ /* used for backwards-compatibility with FT 1.x anyway. */ /* */ - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_raster5_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_raster5_renderer_class, + + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -257,7 +275,7 @@ (FT_Module_Constructor)ft_raster1_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -266,8 +284,8 @@ (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, (FT_Renderer_SetModeFunc) ft_raster1_set_mode, - (FT_Raster_Funcs*) &ft_standard_raster - }; + (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + ) /* END */ diff --git a/lib/3rdparty/freetype/src/raster/ftrend1.h b/lib/3rdparty/freetype/src/raster/ftrend1.h index 76e9a5f581e..4cf128622a9 100644 --- a/lib/3rdparty/freetype/src/raster/ftrend1.h +++ b/lib/3rdparty/freetype/src/raster/ftrend1.h @@ -27,13 +27,13 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster1_renderer_class; + FT_DECLARE_RENDERER( ft_raster1_renderer_class ) /* this renderer is _NOT_ part of the default modules, you'll need */ /* to register it by hand in your application. It should only be */ /* used for backwards-compatibility with FT 1.x anyway. */ /* */ - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster5_renderer_class; + FT_DECLARE_RENDERER( ft_raster5_renderer_class ) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/raster/module.mk b/lib/3rdparty/freetype/src/raster/module.mk index 59c737b9303..cbff5df96ea 100644 --- a/lib/3rdparty/freetype/src/raster/module.mk +++ b/lib/3rdparty/freetype/src/raster/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += RASTER_MODULE define RASTER_MODULE -$(OPEN_DRIVER)ft_raster1_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_raster1_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/raster/raster.c b/lib/3rdparty/freetype/src/raster/raster.c index f13a67a209d..1202a116cdf 100644 --- a/lib/3rdparty/freetype/src/raster/raster.c +++ b/lib/3rdparty/freetype/src/raster/raster.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "rastpic.c" #include "ftraster.c" #include "ftrend1.c" diff --git a/lib/3rdparty/freetype/src/raster/rastpic.c b/lib/3rdparty/freetype/src/raster/rastpic.c new file mode 100644 index 00000000000..3c264877b6d --- /dev/null +++ b/lib/3rdparty/freetype/src/raster/rastpic.c @@ -0,0 +1,89 @@ +/***************************************************************************/ +/* */ +/* rastpic.c */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "rastpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftraster.c */ + void FT_Init_Class_ft_standard_raster(FT_Raster_Funcs*); + + void + ft_raster1_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->raster ) + { + RasterPIC* container = (RasterPIC*)pic_container->raster; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->raster = NULL; + } + } + + + FT_Error + ft_raster1_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + RasterPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve raster5 renderer, + it implements reference counting */ + if(pic_container->raster) + { + ((RasterPIC*)pic_container->raster)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->raster = container; + container->ref_count = 1; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_standard_raster(&container->ft_standard_raster); +/*Exit:*/ + if(error) + ft_raster1_renderer_class_pic_free(library); + return error; + } + + /* re-route these init and free functions to the above functions */ + FT_Error ft_raster5_renderer_class_pic_init(FT_Library library) + { + return ft_raster1_renderer_class_pic_init(library); + } + void ft_raster5_renderer_class_pic_free(FT_Library library) + { + ft_raster1_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/raster/rastpic.h b/lib/3rdparty/freetype/src/raster/rastpic.h new file mode 100644 index 00000000000..dcd82b8ca8f --- /dev/null +++ b/lib/3rdparty/freetype/src/raster/rastpic.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* rastpic.h */ +/* */ +/* The FreeType position independent code services for raster module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __RASTPIC_H__ +#define __RASTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_STANDARD_RASTER_GET ft_standard_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct RasterPIC_ + { + int ref_count; + FT_Raster_Funcs ft_standard_raster; + } RasterPIC; + +#define GET_PIC(lib) ((RasterPIC*)((lib)->pic_container.raster)) +#define FT_STANDARD_RASTER_GET (GET_PIC(library)->ft_standard_raster) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __RASTPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/raster/rules.mk b/lib/3rdparty/freetype/src/raster/rules.mk index 0dc8782ea45..9703b1298a1 100644 --- a/lib/3rdparty/freetype/src/raster/rules.mk +++ b/lib/3rdparty/freetype/src/raster/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001, 2003 by +# Copyright 1996-2000, 2001, 2003, 2008, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/lib/3rdparty/freetype/src/sfnt/Jamfile b/lib/3rdparty/freetype/src/sfnt/Jamfile index 6b8a4018223..cb20b1b04b1 100644 --- a/lib/3rdparty/freetype/src/sfnt/Jamfile +++ b/lib/3rdparty/freetype/src/sfnt/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ttbdf ; + _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; } else { diff --git a/lib/3rdparty/freetype/src/sfnt/module.mk b/lib/3rdparty/freetype/src/sfnt/module.mk index d33913809cc..95fd6a31437 100644 --- a/lib/3rdparty/freetype/src/sfnt/module.mk +++ b/lib/3rdparty/freetype/src/sfnt/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += SFNT_MODULE define SFNT_MODULE -$(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Module_Class, sfnt_module_class $(CLOSE_DRIVER) $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/sfnt/rules.mk b/lib/3rdparty/freetype/src/sfnt/rules.mk index ff7840e7fe3..abda74fcaaa 100644 --- a/lib/3rdparty/freetype/src/sfnt/rules.mk +++ b/lib/3rdparty/freetype/src/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007 by +# Copyright 1996-2000, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -37,8 +37,11 @@ SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ # SFNT driver headers # -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ - $(SFNT_DIR)/sferrors.h +# Note that ttsbit0.c gets #included by ttsbit.c. +# +SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ + $(SFNT_DIR)/sferrors.h \ + $(SFNT_DIR)/ttsbit0.c # SFNT driver object(s) diff --git a/lib/3rdparty/freetype/src/sfnt/sfdriver.c b/lib/3rdparty/freetype/src/sfnt/sfdriver.c index 5ba22a6c51c..1097efb86d7 100644 --- a/lib/3rdparty/freetype/src/sfnt/sfdriver.c +++ b/lib/3rdparty/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,12 +17,14 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_OBJECTS_H #include "sfdriver.h" #include "ttload.h" #include "sfobjs.h" +#include "sfntpic.h" #include "sferrors.h" @@ -48,6 +50,15 @@ #include FT_SERVICE_SFNT_H #include FT_SERVICE_TT_CMAP_H + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_sfdriver + /* * SFNT TABLE SERVICE @@ -103,27 +114,28 @@ sfnt_table_info( TT_Face face, FT_UInt idx, FT_ULong *tag, + FT_ULong *offset, FT_ULong *length ) { - if ( !tag || !length ) + if ( !tag || !offset || !length ) return SFNT_Err_Invalid_Argument; if ( idx >= face->num_tables ) return SFNT_Err_Table_Missing; *tag = face->dir_tables[idx].Tag; + *offset = face->dir_tables[idx].Offset; *length = face->dir_tables[idx].Length; return SFNT_Err_Ok; } - static const FT_Service_SFNT_TableRec sfnt_service_sfnt_table = - { + FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table, (FT_SFNT_TableLoadFunc)tt_face_load_any, (FT_SFNT_TableGetFunc) get_sfnt_table, (FT_SFNT_TableInfoFunc)sfnt_table_info - }; + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -151,11 +163,43 @@ } - static const FT_Service_GlyphDictRec sfnt_service_glyph_dict = + static FT_UInt + sfnt_get_name_index( TT_Face face, + FT_String* glyph_name ) { + FT_Face root = &face->root; + FT_UInt i, max_gid = FT_UINT_MAX; + + + if ( root->num_glyphs < 0 ) + return 0; + else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX ) + max_gid = ( FT_UInt ) root->num_glyphs; + else + FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", + FT_UINT_MAX, root->num_glyphs )); + + for ( i = 0; i < max_gid; i++ ) + { + FT_String* gname; + FT_Error error = tt_face_get_ps_name( face, i, &gname ); + + + if ( error ) + continue; + + if ( !ft_strcmp( glyph_name, gname ) ) + return i; + } + + return 0; + } + + + FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict, (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)NULL - }; + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index + ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -275,19 +319,17 @@ return result; } - static const FT_Service_PsFontNameRec sfnt_service_ps_name = - { + FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name, (FT_PsName_GetFunc)sfnt_get_ps_name - }; + ) /* * TT CMAP INFO */ - static const FT_Service_TTCMapsRec tt_service_get_cmap_info = - { + FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info, (TT_CMap_Info_GetFunc)tt_get_cmap_info - }; + ) #ifdef TT_CONFIG_OPTION_BDF @@ -328,11 +370,10 @@ } - static const FT_Service_BDFRec sfnt_service_bdf = - { + FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf, (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop, - }; + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -341,20 +382,35 @@ * SERVICE LIST */ - static const FT_ServiceDescRec sfnt_services[] = - { - { FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table }, - { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name }, -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - { FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict }, +#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC5(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#elif defined TT_CONFIG_OPTION_BDF + FT_DEFINE_SERVICEDESCREC4(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET + ) #endif -#ifdef TT_CONFIG_OPTION_BDF - { FT_SERVICE_ID_BDF, &sfnt_service_bdf }, -#endif - { FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info }, - - { NULL, NULL } - }; FT_CALLBACK_DEF( FT_Module_Interface ) @@ -363,7 +419,7 @@ { FT_UNUSED( module ); - return ft_service_list_lookup( sfnt_services, module_interface ); + return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface ); } @@ -494,10 +550,18 @@ #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define PUT_EMBEDDED_BITMAPS(a) a +#else +#define PUT_EMBEDDED_BITMAPS(a) 0 +#endif +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#define PUT_PS_NAMES(a) a +#else +#define PUT_PS_NAMES(a) 0 +#endif - static - const SFNT_Interface sfnt_interface = - { + FT_DEFINE_SFNT_INTERFACE(sfnt_interface, tt_face_goto_table, sfnt_init_face, @@ -507,10 +571,8 @@ tt_face_load_any, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_sfnt_header_stub, - tt_face_load_directory_stub, -#endif + tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ tt_face_load_head, tt_face_load_hhea, @@ -522,53 +584,32 @@ tt_face_load_name, tt_face_free_name, -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_hdmx_stub, - tt_face_free_hdmx_stub, -#endif + tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ tt_face_load_kern, tt_face_load_gasp, tt_face_load_pclt, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttload.h' */ - tt_face_load_bhed, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_bhed), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_set_sbit_strike_stub, - tt_face_load_sbit_stub, + tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ - tt_find_sbit_image, - tt_load_sbit_metrics, -#endif + tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_face_load_sbit_image, -#else - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_free_sbit_stub, -#endif + tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES /* see `ttpost.h' */ - tt_face_get_ps_name, - tt_face_free_ps_names, -#else - 0, - 0, -#endif + PUT_PS_NAMES(tt_face_get_ps_name), + PUT_PS_NAMES(tt_face_free_ps_names), -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - tt_face_load_charmap_stub, - tt_face_free_charmap_stub, -#endif + tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */ /* since version 2.1.8 */ @@ -579,27 +620,19 @@ tt_face_load_font_dir, tt_face_load_hmtx, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* see `ttsbit.h' and `sfnt.h' */ - tt_face_load_eblc, - tt_face_free_eblc, + PUT_EMBEDDED_BITMAPS(tt_face_load_eblc), + PUT_EMBEDDED_BITMAPS(tt_face_free_eblc), - tt_face_set_sbit_strike, - tt_face_load_strike_metrics, -#else - 0, - 0, - 0, - 0, -#endif + PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike), + PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics), tt_face_get_metrics - }; + ) - FT_CALLBACK_TABLE_DEF - const FT_Module_Class sfnt_module_class = - { + FT_DEFINE_MODULE(sfnt_module_class, + 0, /* not a font driver or renderer */ sizeof( FT_ModuleRec ), @@ -607,12 +640,12 @@ 0x10000L, /* driver version 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or higher */ - (const void*)&sfnt_interface, /* module specific interface */ + (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) sfnt_get_interface - }; + ) /* END */ diff --git a/lib/3rdparty/freetype/src/sfnt/sfdriver.h b/lib/3rdparty/freetype/src/sfnt/sfdriver.h index 92db79694d0..5de25d51ca4 100644 --- a/lib/3rdparty/freetype/src/sfnt/sfdriver.h +++ b/lib/3rdparty/freetype/src/sfnt/sfdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; + FT_DECLARE_MODULE( sfnt_module_class ) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/sfnt/sfnt.c b/lib/3rdparty/freetype/src/sfnt/sfnt.c index 45a820b718d..fc507b49613 100644 --- a/lib/3rdparty/freetype/src/sfnt/sfnt.c +++ b/lib/3rdparty/freetype/src/sfnt/sfnt.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "sfntpic.c" #include "ttload.c" #include "ttmtx.c" #include "ttcmap.c" diff --git a/lib/3rdparty/freetype/src/sfnt/sfntpic.c b/lib/3rdparty/freetype/src/sfnt/sfntpic.c new file mode 100644 index 00000000000..fd3cf4e923e --- /dev/null +++ b/lib/3rdparty/freetype/src/sfnt/sfntpic.c @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* sfntpic.c */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "sfntpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from sfdriver.c */ + FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*); + void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*); + void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*); + void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*); + void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*); + void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*); + + /* forward declaration of PIC init functions from ttcmap.c */ + FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**); + void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*); + + void + sfnt_module_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->sfnt ) + { + sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt; + if(container->sfnt_services) + FT_Destroy_Class_sfnt_services(library, container->sfnt_services); + container->sfnt_services = NULL; + if(container->tt_cmap_classes) + FT_Destroy_Class_tt_cmap_classes(library, container->tt_cmap_classes); + container->tt_cmap_classes = NULL; + FT_FREE( container ); + pic_container->sfnt = NULL; + } + } + + + FT_Error + sfnt_module_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + sfntModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->sfnt = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_sfnt_services(library, &container->sfnt_services); + if(error) + goto Exit; + error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes); + if(error) + goto Exit; + FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict); + FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name); + FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info); + FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table); +#ifdef TT_CONFIG_OPTION_BDF + FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf); +#endif + FT_Init_Class_sfnt_interface(library, &container->sfnt_interface); + +Exit: + if(error) + sfnt_module_class_pic_free(library); + return error; + } + + + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/sfnt/sfntpic.h b/lib/3rdparty/freetype/src/sfnt/sfntpic.h new file mode 100644 index 00000000000..6943b4250a2 --- /dev/null +++ b/lib/3rdparty/freetype/src/sfnt/sfntpic.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* sfntpic.h */ +/* */ +/* The FreeType position independent code services for sfnt module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFNTPIC_H__ +#define __SFNTPIC_H__ + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_PIC_H + + #ifndef FT_CONFIG_OPTION_PIC +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict +#define FT_SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name +#define FT_TT_SERVICE_GET_CMAP_INFO_GET tt_service_get_cmap_info +#define FT_SFNT_SERVICES_GET sfnt_services +#define FT_TT_CMAP_CLASSES_GET tt_cmap_classes +#define FT_SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table +#define FT_SFNT_SERVICE_BDF_GET sfnt_service_bdf +#define FT_SFNT_INTERFACE_GET sfnt_interface + +#else /* FT_CONFIG_OPTION_PIC */ + +/* some include files required for members of sfntModulePIC */ +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H +#ifdef TT_CONFIG_OPTION_BDF +#include "ttbdf.h" +#include FT_SERVICE_BDF_H +#endif +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include "ttcmap.h" + +typedef struct sfntModulePIC_ + { + FT_ServiceDescRec* sfnt_services; + FT_Service_GlyphDictRec sfnt_service_glyph_dict; + FT_Service_PsFontNameRec sfnt_service_ps_name; + FT_Service_TTCMapsRec tt_service_get_cmap_info; + TT_CMap_Class* tt_cmap_classes; + FT_Service_SFNT_TableRec sfnt_service_sfnt_table; +#ifdef TT_CONFIG_OPTION_BDF + FT_Service_BDFRec sfnt_service_bdf; +#endif + SFNT_Interface sfnt_interface; + } sfntModulePIC; + +#define GET_PIC(lib) ((sfntModulePIC*)((lib)->pic_container.sfnt)) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_SFNT_SERVICE_GLYPH_DICT_GET (GET_PIC(library)->sfnt_service_glyph_dict) +#define FT_SFNT_SERVICE_PS_NAME_GET (GET_PIC(library)->sfnt_service_ps_name) +#define FT_TT_SERVICE_GET_CMAP_INFO_GET (GET_PIC(library)->tt_service_get_cmap_info) +#define FT_SFNT_SERVICES_GET (GET_PIC(library)->sfnt_services) +#define FT_TT_CMAP_CLASSES_GET (GET_PIC(library)->tt_cmap_classes) +#define FT_SFNT_SERVICE_SFNT_TABLE_GET (GET_PIC(library)->sfnt_service_sfnt_table) +#define FT_SFNT_SERVICE_BDF_GET (GET_PIC(library)->sfnt_service_bdf) +#define FT_SFNT_INTERFACE_GET (GET_PIC(library)->sfnt_interface) + +#endif /* FT_CONFIG_OPTION_PIC */ + +/* */ + +FT_END_HEADER + +#endif /* __SFNTPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/sfnt/sfobjs.c b/lib/3rdparty/freetype/src/sfnt/sfobjs.c index cc901100d1d..b74b1a93a9b 100644 --- a/lib/3rdparty/freetype/src/sfnt/sfobjs.c +++ b/lib/3rdparty/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SFNT_NAMES_H #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -123,14 +124,20 @@ /* */ /* nameid :: The name id of the name record to return. */ /* */ - /* <Return> */ - /* Character string. NULL if no name is present. */ + /* <InOut> */ + /* name :: The address of a string pointer. NULL if no name is */ + /* present. */ /* */ - static FT_String* - tt_face_get_name( TT_Face face, - FT_UShort nameid ) + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ) { FT_Memory memory = face->root.memory; + FT_Error error = SFNT_Err_Ok; FT_String* result = NULL; FT_UShort n; TT_NameEntryRec* rec; @@ -145,6 +152,8 @@ TT_NameEntry_ConvertFunc convert; + FT_ASSERT( name ); + rec = face->name_table.names; for ( n = 0; n < face->num_names; n++, rec++ ) { @@ -256,11 +265,8 @@ { if ( rec->string == NULL ) { - FT_Error error = SFNT_Err_Ok; FT_Stream stream = face->name_table.stream; - FT_UNUSED( error ); - if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || FT_STREAM_SEEK( rec->stringOffset ) || @@ -277,7 +283,8 @@ } Exit: - return result; + *name = result; + return error; } @@ -285,7 +292,7 @@ sfnt_find_encoding( int platform_id, int encoding_id ) { - typedef struct TEncoding + typedef struct TEncoding_ { int platform_id; int encoding_id; @@ -363,11 +370,12 @@ if ( FT_READ_ULONG( tag ) ) return error; - if ( tag != 0x00010000UL && - tag != TTAG_ttcf && - tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) && - tag != TTAG_true && - tag != 0x00020000UL ) + if ( tag != 0x00010000UL && + tag != TTAG_ttcf && + tag != TTAG_OTTO && + tag != TTAG_true && + tag != TTAG_typ1 && + tag != 0x00020000UL ) return SFNT_Err_Unknown_File_Format; face->ttc_header.tag = TTAG_ttcf; @@ -401,7 +409,7 @@ face->ttc_header.version = 1 << 16; face->ttc_header.count = 1; - if ( FT_NEW( face->ttc_header.offsets) ) + if ( FT_NEW( face->ttc_header.offsets ) ) return error; face->ttc_header.offsets[0] = offset; @@ -451,7 +459,7 @@ face_index = 0; if ( face_index >= face->ttc_header.count ) - return SFNT_Err_Bad_Argument; + return SFNT_Err_Invalid_Argument; if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; @@ -461,7 +469,8 @@ if ( error ) return error; - face->root.num_faces = face->ttc_header.count; + face->root.num_faces = face->ttc_header.count; + face->root.face_index = face_index; return error; } @@ -498,6 +507,13 @@ FT_TRACE3(( "\n" )); \ } while ( 0 ) +#define GET_NAME( id, field ) \ + do { \ + error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \ + if ( error ) \ + goto Exit; \ + } while ( 0 ) + FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, @@ -506,16 +522,33 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error, psnames_error; + FT_Error error; +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Error psnames_error; +#endif FT_Bool has_outline; FT_Bool is_apple_sbit; + FT_Bool ignore_preferred_family = FALSE; + FT_Bool ignore_preferred_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_UNUSED( face_index ); - FT_UNUSED( num_params ); - FT_UNUSED( params ); + /* Check parameters */ + + { + FT_Int i; + + + for ( i = 0; i < num_params; i++ ) + { + if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) + ignore_preferred_family = TRUE; + else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) + ignore_preferred_subfamily = TRUE; + } + } /* Load tables */ @@ -581,7 +614,10 @@ /* don't check for errors */ LOAD_( name ); LOAD_( post ); + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES psnames_error = error; +#endif /* do not load the metrics headers and tables if this is an Apple */ /* sbit font file */ @@ -660,19 +696,20 @@ face->os2.version = 0xFFFFU; } - } /* the optional tables */ - /* embedded bitmap support. */ + /* embedded bitmap support */ if ( sfnt->load_eblc ) { LOAD_( eblc ); if ( error ) { - /* return an error if this font file has no outlines */ - if ( error == SFNT_Err_Table_Missing && has_outline ) + /* a font which contains neither bitmaps nor outlines is */ + /* still valid (although rather useless in most cases); */ + /* however, you can find such stripped fonts in PDFs */ + if ( error == SFNT_Err_Table_Missing ) error = SFNT_Err_Ok; else goto Exit; @@ -692,26 +729,47 @@ LOAD_( gasp ); LOAD_( kern ); - error = SFNT_Err_Ok; - face->root.num_glyphs = face->max_profile.numGlyphs; - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_FAMILY ); - if ( !face->root.family_name ) - face->root.family_name = tt_face_get_name( face, - TT_NAME_ID_FONT_FAMILY ); + /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ + /* a WWS-only font face. `WWS' stands for `weight', width', and */ + /* `slope', a term used by Microsoft's Windows Presentation */ + /* Foundation (WPF). This flag has been introduced in version */ + /* 1.5 of the OpenType specification (May 2008). */ - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_PREFERRED_SUBFAMILY ); - if ( !face->root.style_name ) - face->root.style_name = tt_face_get_name( face, - TT_NAME_ID_FONT_SUBFAMILY ); + face->root.family_name = NULL; + face->root.style_name = NULL; + if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) + { + if ( !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + if ( !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } + else + { + GET_NAME( WWS_FAMILY, &face->root.family_name ); + if ( !face->root.family_name && !ignore_preferred_family ) + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name ) + GET_NAME( FONT_FAMILY, &face->root.family_name ); + + GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name && !ignore_preferred_subfamily ) + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name ) + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); + } /* now set up root fields */ { - FT_Face root = &face->root; - FT_Int32 flags = root->face_flags; + FT_Face root = &face->root; + FT_Long flags = root->face_flags; /*********************************************************************/ @@ -727,7 +785,7 @@ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( psnames_error == SFNT_Err_Ok && + if ( psnames_error == SFNT_Err_Ok && face->postscript.FormatType != 0x00030000L ) flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif @@ -759,19 +817,26 @@ /* */ /* Compute style flags. */ /* */ + flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { - /* we have an OS/2 table; use the `fsSelection' field */ - if ( face->os2.fsSelection & 1 ) + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag has been */ + /* introduced in version 1.5 of the OpenType specification. */ + + if ( face->os2.fsSelection & 512 ) /* bit 9 */ + flags |= FT_STYLE_FLAG_ITALIC; + else if ( face->os2.fsSelection & 1 ) /* bit 0 */ flags |= FT_STYLE_FLAG_ITALIC; - if ( face->os2.fsSelection & 32 ) + if ( face->os2.fsSelection & 32 ) /* bit 5 */ flags |= FT_STYLE_FLAG_BOLD; } else { /* this is an old Mac font, use the header field */ + if ( face->header.Mac_Style & 1 ) flags |= FT_STYLE_FLAG_BOLD; @@ -816,12 +881,78 @@ } } +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* + * Now allocate the root array of FT_Bitmap_Size records and + * populate them. Unfortunately, it isn't possible to indicate bit + * depths in the FT_Bitmap_Size record. This is a design error. + */ + { + FT_UInt i, count; + + +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + count = face->sbit_num_strikes; +#else + count = (FT_UInt)face->num_sbit_strikes; +#endif + + if ( count > 0 ) + { + FT_Memory memory = face->root.stream->memory; + FT_UShort em_size = face->header.Units_Per_EM; + FT_Short avgwidth = face->os2.xAvgCharWidth; + FT_Size_Metrics metrics; + + + if ( em_size == 0 || face->os2.version == 0xFFFFU ) + { + avgwidth = 0; + em_size = 1; + } + + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; + + for ( i = 0; i < count; i++ ) + { + FT_Bitmap_Size* bsize = root->available_sizes + i; + + + error = sfnt->load_strike_metrics( face, i, &metrics ); + if ( error ) + goto Exit; + + bsize->height = (FT_Short)( metrics.height >> 6 ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + + bsize->x_ppem = metrics.x_ppem << 6; + bsize->y_ppem = metrics.y_ppem << 6; + + /* assume 72dpi */ + bsize->size = metrics.y_ppem << 6; + } + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)count; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* a font with no bitmaps and no outlines is scalable; */ + /* it has only empty glyphs then */ + if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) + root->face_flags |= FT_FACE_FLAG_SCALABLE; + /*********************************************************************/ /* */ /* Set up metrics. */ /* */ - if ( has_outline == TRUE ) + if ( FT_IS_SCALABLE( root ) ) { /* XXX What about if outline header is missing */ /* (e.g. sfnt wrapped bitmap)? */ @@ -874,10 +1005,9 @@ /* this computation is based on various versions of Times New Roman */ if ( face->horizontal.Line_Gap == 0 ) root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); -#endif +#endif /* 0 */ #if 0 - /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ if ( face->os2.version != 0xFFFFU && root->ascender ) @@ -892,80 +1022,21 @@ if ( height > root->height ) root->height = height; } - #endif /* 0 */ - root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_height = (FT_Short)( face->vertical_info + ? face->vertical.advance_Height_Max + : root->height ); - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); - - root->underline_position = face->postscript.underlinePosition; + /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ + /* Adjust underline position from top edge to centre of */ + /* stroke to convert TrueType meaning to FreeType meaning. */ + root->underline_position = face->postscript.underlinePosition - + face->postscript.underlineThickness / 2; root->underline_thickness = face->postscript.underlineThickness; } -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* - * Now allocate the root array of FT_Bitmap_Size records and - * populate them. Unfortunately, it isn't possible to indicate bit - * depths in the FT_Bitmap_Size record. This is a design error. - */ - { - FT_UInt i, count; - - -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS - count = face->sbit_num_strikes; -#else - count = (FT_UInt)face->num_sbit_strikes; -#endif - - if ( count > 0 ) - { - FT_Memory memory = face->root.stream->memory; - FT_UShort em_size = face->header.Units_Per_EM; - FT_Short avgwidth = face->os2.xAvgCharWidth; - FT_Size_Metrics metrics; - - - if ( em_size == 0 || face->os2.version == 0xFFFFU ) - { - avgwidth = 0; - em_size = 1; - } - - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) - goto Exit; - - for ( i = 0; i < count; i++ ) - { - FT_Bitmap_Size* bsize = root->available_sizes + i; - - - error = sfnt->load_strike_metrics( face, i, &metrics ); - if ( error ) - goto Exit; - - bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); - - bsize->x_ppem = metrics.x_ppem << 6; - bsize->y_ppem = metrics.y_ppem << 6; - - /* assume 72dpi */ - bsize->size = metrics.y_ppem << 6; - } - - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - } Exit: @@ -977,15 +1048,22 @@ #undef LOAD_ #undef LOADM_ +#undef GET_NAME FT_LOCAL_DEF( void ) sfnt_done_face( TT_Face face ) { - FT_Memory memory = face->root.memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + FT_Memory memory; + SFNT_Service sfnt; + if ( !face ) + return; + + memory = face->root.memory; + sfnt = (SFNT_Service)face->sfnt; + if ( sfnt ) { /* destroy the postscript names table if it is loaded */ @@ -1023,7 +1101,7 @@ } /* freeing the horizontal metrics */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS { FT_Stream stream = FT_FACE_STREAM( face ); @@ -1051,7 +1129,8 @@ face->gasp.numRanges = 0; /* freeing the name table */ - sfnt->free_name( face ); + if ( sfnt ) + sfnt->free_name( face ); /* freeing family and style name */ FT_FREE( face->root.family_name ); diff --git a/lib/3rdparty/freetype/src/sfnt/ttbdf.c b/lib/3rdparty/freetype/src/sfnt/ttbdf.c index 6c95387adb8..206cecee5ed 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttbdf.c +++ b/lib/3rdparty/freetype/src/sfnt/ttbdf.c @@ -84,7 +84,7 @@ FT_Byte* p = bdf->table; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt num_strikes = FT_NEXT_USHORT( p ); - FT_UInt32 strings = FT_NEXT_ULONG ( p ); + FT_ULong strings = FT_NEXT_ULONG ( p ); FT_UInt count; FT_Byte* strike; @@ -141,13 +141,13 @@ const char* property_name, BDF_PropertyRec *aprop ) { - TT_BDF bdf = &face->bdf; - FT_Size size = FT_FACE(face)->size; - FT_Error error = 0; - FT_Byte* p; - FT_UInt count; - FT_Byte* strike; - FT_UInt property_len; + TT_BDF bdf = &face->bdf; + FT_Size size = FT_FACE(face)->size; + FT_Error error = 0; + FT_Byte* p; + FT_UInt count; + FT_Byte* strike; + FT_Offset property_len; aprop->type = BDF_PROPERTY_TYPE_NONE; diff --git a/lib/3rdparty/freetype/src/sfnt/ttcmap.c b/lib/3rdparty/freetype/src/sfnt/ttcmap.c index 2da43360eb6..b283f6d1621 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttcmap.c +++ b/lib/3rdparty/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include FT_INTERNAL_STREAM_H #include "ttload.h" #include "ttcmap.h" +#include "sfntpic.h" /*************************************************************************/ @@ -39,11 +40,13 @@ #define TT_PEEK_SHORT FT_PEEK_SHORT #define TT_PEEK_USHORT FT_PEEK_USHORT +#define TT_PEEK_UINT24 FT_PEEK_UOFF3 #define TT_PEEK_LONG FT_PEEK_LONG #define TT_PEEK_ULONG FT_PEEK_ULONG #define TT_NEXT_SHORT FT_NEXT_SHORT #define TT_NEXT_USHORT FT_NEXT_USHORT +#define TT_NEXT_UINT24 FT_NEXT_UOFF3 #define TT_NEXT_LONG FT_NEXT_LONG #define TT_NEXT_ULONG FT_NEXT_ULONG @@ -122,7 +125,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap0_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -132,7 +135,7 @@ FT_UInt gindex = 0; - table += 6; /* go to glyph ids */ + table += 6; /* go to glyph IDs */ while ( ++charcode < 256 ) { gindex = table[charcode]; @@ -155,28 +158,27 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 0; + cmap_info->format = 0; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap0_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap0_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap0_char_next, + + NULL, NULL, NULL, NULL, NULL + , 0, (TT_CMap_ValidateFunc) tt_cmap0_validate, (TT_CMap_Info_GetFunc) tt_cmap0_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -227,7 +229,7 @@ /* language 4 USHORT Mac language code */ /* keys 6 USHORT[256] sub-header keys */ /* subs 518 SUBHEAD[NSUBS] sub-headers array */ - /* glyph_ids 518+NSUB*8 USHORT[] glyph id array */ + /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ /* */ /* The `keys' table is used to map charcode high-bytes to sub-headers. */ /* The value of `NSUBS' is the number of sub-headers defined in the */ @@ -256,14 +258,14 @@ /* */ /* * The value of `offset' is read. This is a _byte_ distance from the */ /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it's a USHORT[] too). */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ /* */ /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ /* no glyph for the charcode. Otherwise, the value of `delta' is */ /* added to it (modulo 65536) to form a new glyph index. */ /* */ /* It is up to the validation routine to check that all offsets fall */ - /* within the glyph ids table (and not within the `subs' table itself or */ + /* within the glyph IDs table (and not within the `subs' table itself or */ /* outside of the CMap). */ /* */ @@ -278,7 +280,7 @@ FT_UInt n, max_subs; FT_Byte* keys; /* keys table */ FT_Byte* subs; /* sub-headers */ - FT_Byte* glyph_ids; /* glyph id array */ + FT_Byte* glyph_ids; /* glyph ID array */ if ( table + length > valid->limit || length < 6 + 512 ) @@ -324,6 +326,10 @@ delta = TT_NEXT_SHORT( p ); offset = TT_NEXT_USHORT( p ); + /* many Dynalab fonts have empty sub-headers */ + if ( code_count == 0 ) + continue; + /* check range within 0..255 */ if ( valid->level >= FT_VALIDATE_PARANOID ) { @@ -338,7 +344,7 @@ if ( ids < glyph_ids || ids + code_count*2 > table + length ) FT_INVALID_OFFSET; - /* check glyph ids */ + /* check glyph IDs */ if ( valid->level >= FT_VALIDATE_TIGHT ) { FT_Byte* limit = p + code_count * 2; @@ -389,7 +395,7 @@ sub = subs; /* jump to first sub-header */ /* check that the sub-header for this byte is 0, which */ - /* indicates that it's really a valid one-byte value */ + /* indicates that it is really a valid one-byte value */ /* Otherwise, return 0 */ /* */ p += char_lo * 2; @@ -454,7 +460,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap2_char_next( TT_CMap cmap, FT_UInt32 *pcharcode ) { @@ -528,28 +534,27 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 2; + cmap_info->format = 2; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap2_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap2_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap2_char_next, + + NULL, NULL, NULL, NULL, NULL + , 2, (TT_CMap_ValidateFunc) tt_cmap2_validate, (TT_CMap_Info_GetFunc) tt_cmap2_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -595,14 +600,14 @@ /* each segment; can be */ /* zero */ /* */ - /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph id */ + /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ /* ranges */ /* */ /* Character codes are modelled by a series of ordered (increasing) */ /* intervals called segments. Each segment has start and end codes, */ /* provided by the `startCount' and `endCount' arrays. Segments must */ - /* not be overlapping and the last segment should always contain the */ - /* `0xFFFF' endCount. */ + /* not overlap, and the last segment should always contain the value */ + /* 0xFFFF for `endCount'. */ /* */ /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ /* ignored (they are traces of over-engineering in the TrueType */ @@ -615,14 +620,14 @@ /* charcode within the segment is obtained by adding the value of */ /* `idDelta' directly to the charcode, modulo 65536. */ /* */ - /* Otherwise, a glyph index is taken from the glyph ids sub-array for */ + /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ /* the segment, and the value of `idDelta' is added to it. */ /* */ /* */ - /* Finally, note that certain fonts contain invalid charmaps that */ - /* contain end=0xFFFF, start=0xFFFF, delta=0x0001, offset=0xFFFF at the */ - /* of their charmaps (e.g. opens___.ttf which comes with OpenOffice.org) */ - /* we need special code to deal with them correctly... */ + /* Finally, note that a lot of fonts contain an invalid last segment, */ + /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ + /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ + /* OpenOffice.org). We need special code to deal with them correctly. */ /* */ #ifdef TT_CONFIG_CMAP_FORMAT_4 @@ -654,7 +659,7 @@ p = table + 6; cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; return SFNT_Err_Ok; @@ -687,6 +692,23 @@ p += num_ranges * 2; offset = FT_PEEK_USHORT( p ); + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( range_index >= num_ranges - 1 && + cmap->cur_start == 0xFFFFU && + cmap->cur_end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + cmap->cur_delta = 1; + offset = 0; + } + } + if ( offset != 0xFFFFU ) { cmap->cur_values = offset ? p + offset : NULL; @@ -715,7 +737,7 @@ if ( cmap->cur_charcode >= 0xFFFFUL ) goto Fail; - charcode = cmap->cur_charcode + 1; + charcode = (FT_UInt)cmap->cur_charcode + 1; if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; @@ -777,7 +799,7 @@ } Fail: - cmap->cur_charcode = 0xFFFFFFFFUL; + cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; cmap->cur_gindex = 0; } @@ -825,7 +847,7 @@ /* */ if ( valid->level >= FT_VALIDATE_PARANOID ) { - /* check the values of 'searchRange', 'entrySelector', 'rangeShift' */ + /* check the values of `searchRange', `entrySelector', `rangeShift' */ FT_UInt search_range = TT_NEXT_USHORT( p ); FT_UInt entry_selector = TT_NEXT_USHORT( p ); FT_UInt range_shift = TT_NEXT_USHORT( p ); @@ -852,7 +874,7 @@ offsets = deltas + num_segs * 2; glyph_ids = offsets + num_segs * 2; - /* check last segment, its end count must be FFFF */ + /* check last segment; its end count value must be 0xFFFF */ if ( valid->level >= FT_VALIDATE_PARANOID ) { p = ends + ( num_segs - 1 ) * 2; @@ -861,9 +883,9 @@ } { - FT_UInt start, end, offset, n; - FT_UInt last_start = 0, last_end = 0; - FT_Int delta; + FT_UInt start, end, offset, n; + FT_UInt last_start = 0, last_end = 0; + FT_Int delta; FT_Byte* p_start = starts; FT_Byte* p_end = ends; FT_Byte* p_delta = deltas; @@ -881,10 +903,10 @@ if ( start > end ) FT_INVALID_DATA; - /* this test should be performed at default validation level; */ - /* unfortunately, some popular Asian fonts present overlapping */ - /* ranges in their charmaps */ - /* */ + /* this test should be performed at default validation level; */ + /* unfortunately, some popular Asian fonts have overlapping */ + /* ranges in their charmaps */ + /* */ if ( start <= last_end && n > 0 ) { if ( valid->level >= FT_VALIDATE_TIGHT ) @@ -892,7 +914,7 @@ else { /* allow overlapping segments, provided their start points */ - /* and end points, respectively, are in ascending order. */ + /* and end points, respectively, are in ascending order */ /* */ if ( last_start > start || last_end > end ) error |= TT_CMAP_FLAG_UNSORTED; @@ -903,16 +925,27 @@ if ( offset && offset != 0xFFFFU ) { - p += offset; /* start of glyph id array */ + p += offset; /* start of glyph ID array */ - /* check that we point within the glyph ids table only */ + /* check that we point within the glyph IDs table only */ if ( valid->level >= FT_VALIDATE_TIGHT ) { if ( p < glyph_ids || p + ( end - start + 1 ) * 2 > table + length ) FT_INVALID_DATA; } - else + /* Some fonts handle the last segment incorrectly. In */ + /* theory, 0xFFFF might point to an ordinary glyph -- */ + /* a cmap 4 is versatile and could be used for any */ + /* encoding, not only Unicode. However, reality shows */ + /* that far too many fonts are sloppy and incorrectly */ + /* set all fields but `start' and `end' for the last */ + /* segment if it contains only a single character. */ + /* */ + /* We thus omit the test here, delaying it to the */ + /* routines which actually access the cmap. */ + else if ( n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) { if ( p < glyph_ids || p + ( end - start + 1 ) * 2 > valid->limit ) @@ -940,12 +973,12 @@ } else if ( offset == 0xFFFFU ) { - /* Some fonts (erroneously?) use a range offset of 0xFFFF */ + /* some fonts (erroneously?) use a range offset of 0xFFFF */ /* to mean missing glyph in cmap table */ /* */ - if ( valid->level >= FT_VALIDATE_PARANOID || - n != num_segs - 1 || - !( start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U ) ) + if ( valid->level >= FT_VALIDATE_PARANOID || + n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU ) ) FT_INVALID_DATA; } @@ -959,9 +992,9 @@ static FT_UInt - tt_cmap4_char_map_linear( TT_CMap cmap, - FT_UInt* pcharcode, - FT_Bool next ) + tt_cmap4_char_map_linear( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) { FT_UInt num_segs2, start, end, offset; FT_Int delta; @@ -1003,6 +1036,22 @@ p += num_segs2; offset = TT_PEEK_USHORT( p ); + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + if ( offset == 0xFFFFU ) continue; @@ -1032,14 +1081,14 @@ static FT_UInt - tt_cmap4_char_map_binary( TT_CMap cmap, - FT_UInt* pcharcode, - FT_Bool next ) + tt_cmap4_char_map_binary( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) { FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; - FT_UInt charcode = *pcharcode; + FT_UInt charcode = (FT_UInt)*pcharcode; FT_UInt gindex = 0; FT_Byte* p; @@ -1082,6 +1131,22 @@ p += num_segs2; offset = TT_PEEK_USHORT( p ); + /* some fonts have an incorrect last segment; */ + /* we have to catch it */ + if ( mid >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU ) + { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + + + if ( offset && p + offset + 2 > limit ) + { + delta = 1; + offset = 0; + } + } + /* search the first segment containing `charcode' */ if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) { @@ -1265,7 +1330,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap4_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1305,27 +1370,26 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 4; + cmap_info->format = 4; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap4_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap4_class_rec, sizeof ( TT_CMap4Rec ), (FT_CMap_InitFunc) tt_cmap4_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap4_char_next, + + NULL, NULL, NULL, NULL, NULL + , 4, (TT_CMap_ValidateFunc) tt_cmap4_validate, (TT_CMap_Info_GetFunc) tt_cmap4_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1351,7 +1415,7 @@ /* */ /* first 6 USHORT first segment code */ /* count 8 USHORT segment size in chars */ - /* glyphIds 10 USHORT[count] glyph ids */ + /* glyphIds 10 USHORT[count] glyph IDs */ /* */ /* A very simplified segment mapping. */ /* */ @@ -1417,7 +1481,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap6_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1465,28 +1529,27 @@ FT_Byte* p = cmap->data + 4; - cmap_info->format = 6; + cmap_info->format = 6; cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap6_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap6_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap6_char_next, + + NULL, NULL, NULL, NULL, NULL + , 6, (TT_CMap_ValidateFunc) tt_cmap6_validate, (TT_CMap_Info_GetFunc) tt_cmap6_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1496,7 +1559,7 @@ /***** *****/ /***** FORMAT 8 *****/ /***** *****/ - /***** It's hard to completely understand what the OpenType spec *****/ + /***** It is hard to completely understand what the OpenType spec *****/ /***** says about this format, but here is my conclusion. *****/ /***** *****/ /***** The purpose of this format is to easily map UTF-16 text to *****/ @@ -1511,7 +1574,7 @@ /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ /***** Area. *****/ /***** *****/ - /***** The 'is32' table embedded in the charmap indicates whether a *****/ + /***** The `is32' table embedded in the charmap indicates whether a *****/ /***** given 16-bit value is in the surrogates area or not. *****/ /***** *****/ /***** So, for any given `char_code', we can assert the following: *****/ @@ -1538,11 +1601,11 @@ /* is32 12 BYTE[8192] 32-bitness bitmap */ /* count 8204 ULONG number of groups */ /* */ - /* This header is followed by 'count' groups of the following format: */ + /* This header is followed by `count' groups of the following format: */ /* */ /* start 0 ULONG first charcode */ /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph id for the group */ + /* startId 8 ULONG start glyph ID for the group */ /* */ #ifdef TT_CONFIG_CMAP_FORMAT_8 @@ -1561,7 +1624,7 @@ FT_INVALID_TOO_SHORT; length = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 8208 ) + if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) FT_INVALID_TOO_SHORT; is32 = table + 12; @@ -1671,7 +1734,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1719,28 +1782,27 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 8; + cmap_info->format = 8; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap8_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap8_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap8_char_next, + + NULL, NULL, NULL, NULL, NULL + , 8, (TT_CMap_ValidateFunc) tt_cmap8_validate, (TT_CMap_Info_GetFunc) tt_cmap8_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -1787,7 +1849,8 @@ p = table + 16; count = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 20 + count * 2 ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 20 + count * 2 ) FT_INVALID_TOO_SHORT; /* check glyph indices */ @@ -1829,7 +1892,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap10_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -1868,28 +1931,27 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 10; + cmap_info->format = 10; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap10_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap10_class_rec, sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap10_char_next, + + NULL, NULL, NULL, NULL, NULL + , 10, (TT_CMap_ValidateFunc) tt_cmap10_validate, (TT_CMap_Info_GetFunc) tt_cmap10_get_info - }; + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -1920,7 +1982,7 @@ /* */ /* start 0 ULONG first charcode */ /* end 4 ULONG last charcode */ - /* startId 8 ULONG start glyph id for the group */ + /* startId 8 ULONG start glyph ID for the group */ /* */ #ifdef TT_CONFIG_CMAP_FORMAT_12 @@ -1970,7 +2032,8 @@ p = table + 12; num_groups = TT_NEXT_ULONG( p ); - if ( table + length > valid->limit || length < 16 + 12 * num_groups ) + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ @@ -2039,7 +2102,7 @@ if ( gindex ) { - cmap->cur_charcode = char_code; + cmap->cur_charcode = char_code;; cmap->cur_gindex = gindex; cmap->cur_group = n; @@ -2147,7 +2210,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) tt_cmap12_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -2165,8 +2228,10 @@ if ( cmap12->valid ) { gindex = cmap12->cur_gindex; + + /* XXX: check cur_charcode overflow is expected */ if ( gindex ) - *pchar_code = cmap12->cur_charcode; + *pchar_code = (FT_UInt32)cmap12->cur_charcode; } else gindex = 0; @@ -2174,7 +2239,8 @@ else gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); - return gindex; + /* XXX: check gindex overflow is expected */ + return (FT_UInt32)gindex; } @@ -2185,66 +2251,1135 @@ FT_Byte* p = cmap->data + 8; - cmap_info->format = 12; + cmap_info->format = 12; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } - FT_CALLBACK_TABLE_DEF - const TT_CMap_ClassRec tt_cmap12_class_rec = - { - { + FT_DEFINE_TT_CMAP(tt_cmap12_class_rec, sizeof ( TT_CMap12Rec ), (FT_CMap_InitFunc) tt_cmap12_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next - }, + (FT_CMap_CharNextFunc) tt_cmap12_char_next, + + NULL, NULL, NULL, NULL, NULL + , 12, (TT_CMap_ValidateFunc) tt_cmap12_validate, (TT_CMap_Info_GetFunc) tt_cmap12_get_info - }; - + ) #endif /* TT_CONFIG_CMAP_FORMAT_12 */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 13 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 13 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* glyphId 8 ULONG glyph ID for the whole group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + + typedef struct TT_CMap13Rec_ + { + TT_CMapRec cmap; + FT_Bool valid; + FT_ULong cur_charcode; + FT_UInt cur_gindex; + FT_ULong cur_group; + FT_ULong num_groups; + + } TT_CMap13Rec, *TT_CMap13; + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_init( TT_CMap13 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 12; + cmap->num_groups = FT_PEEK_ULONG( table ); + + cmap->valid = 0; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, glyph_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + + return SFNT_Err_Ok; + } + + + /* search the index of the charcode next to cmap->cur_charcode */ + /* cmap->cur_group should be set up properly by caller */ + /* */ + static void + tt_cmap13_next( TT_CMap13 cmap ) + { + FT_Byte* p; + FT_ULong start, end, glyph_id, char_code; + FT_ULong n; + FT_UInt gindex; + + + if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) + goto Fail; + + char_code = cmap->cur_charcode + 1; + + n = cmap->cur_group; + + for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) + { + p = cmap->cmap.data + 16 + 12 * n; + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + glyph_id = TT_PEEK_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)glyph_id; + + if ( gindex ) + { + cmap->cur_charcode = char_code;; + cmap->cur_gindex = gindex; + cmap->cur_group = n; + + return; + } + } + } + + Fail: + cmap->valid = 0; + } + + + static FT_UInt + tt_cmap13_char_map_binary( TT_CMap cmap, + FT_UInt32* pchar_code, + FT_Bool next ) + { + FT_UInt gindex = 0; + FT_Byte* p = cmap->data + 12; + FT_UInt32 num_groups = TT_PEEK_ULONG( p ); + FT_UInt32 char_code = *pchar_code; + FT_UInt32 start, end; + FT_UInt32 max, min, mid; + + + if ( !num_groups ) + return 0; + + /* make compiler happy */ + mid = num_groups; + end = 0xFFFFFFFFUL; + + if ( next ) + char_code++; + + min = 0; + max = num_groups; + + /* binary search */ + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = cmap->data + 16 + 12 * mid; + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + max = mid; + else if ( char_code > end ) + min = mid + 1; + else + { + gindex = (FT_UInt)TT_PEEK_ULONG( p ); + + break; + } + } + + if ( next ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + + + /* if `char_code' is not in any group, then `mid' is */ + /* the group nearest to `char_code' */ + /* */ + + if ( char_code > end ) + { + mid++; + if ( mid == num_groups ) + return 0; + } + + cmap13->valid = 1; + cmap13->cur_charcode = char_code; + cmap13->cur_group = mid; + + if ( !gindex ) + { + tt_cmap13_next( cmap13 ); + + if ( cmap13->valid ) + gindex = cmap13->cur_gindex; + } + else + cmap13->cur_gindex = gindex; + + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + + return gindex; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap13_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap13_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + TT_CMap13 cmap13 = (TT_CMap13)cmap; + FT_UInt gindex; + + + if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) + return 0; + + /* no need to search */ + if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) + { + tt_cmap13_next( cmap13 ); + if ( cmap13->valid ) + { + gindex = cmap13->cur_gindex; + if ( gindex ) + *pchar_code = cmap13->cur_charcode; + } + else + gindex = 0; + } + else + gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); + + return gindex; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap13_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->format = 13; + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return SFNT_Err_Ok; + } + + + FT_DEFINE_TT_CMAP(tt_cmap13_class_rec, + sizeof ( TT_CMap13Rec ), + + (FT_CMap_InitFunc) tt_cmap13_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, + (FT_CMap_CharNextFunc) tt_cmap13_char_next, + + NULL, NULL, NULL, NULL, NULL + , + 13, + (TT_CMap_ValidateFunc) tt_cmap13_validate, + (TT_CMap_Info_GetFunc) tt_cmap13_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_13 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 14 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 14 */ + /* length 2 ULONG table length in bytes */ + /* numSelector 6 ULONG number of variation sel. records */ + /* */ + /* Followed by numSelector records, each of which looks like */ + /* */ + /* varSelector 0 UINT24 Unicode codepoint of sel. */ + /* defaultOff 3 ULONG offset to a default UVS table */ + /* describing any variants to be found in */ + /* the normal Unicode subtable. */ + /* nonDefOff 7 ULONG offset to a non-default UVS table */ + /* describing any variants not in the */ + /* standard cmap, with GIDs here */ + /* (either offset may be 0 NULL) */ + /* */ + /* Selectors are sorted by code point. */ + /* */ + /* A default Unicode Variation Selector (UVS) subtable is just a list of */ + /* ranges of code points which are to be found in the standard cmap. No */ + /* glyph IDs (GIDs) here. */ + /* */ + /* numRanges 0 ULONG number of ranges following */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* additionalCnt 3 UBYTE count of additional characters in this */ + /* range (zero means a range of a single */ + /* character) */ + /* */ + /* Ranges are sorted by `uniStart'. */ + /* */ + /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ + /* mappings from codepoint to GID. */ + /* */ + /* numMappings 0 ULONG number of mappings */ + /* */ + /* A range looks like */ + /* */ + /* uniStart 0 UINT24 code point of the first character in */ + /* this range */ + /* GID 3 USHORT and its GID */ + /* */ + /* Ranges are sorted by `uniStart'. */ + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + + typedef struct TT_CMap14Rec_ + { + TT_CMapRec cmap; + FT_ULong num_selectors; + + /* This array is used to store the results of various + * cmap 14 query functions. The data is overwritten + * on each call to these functions. + */ + FT_UInt32 max_results; + FT_UInt32* results; + FT_Memory memory; + + } TT_CMap14Rec, *TT_CMap14; + + + FT_CALLBACK_DEF( void ) + tt_cmap14_done( TT_CMap14 cmap ) + { + FT_Memory memory = cmap->memory; + + + cmap->max_results = 0; + if ( memory != NULL && cmap->results != NULL ) + FT_FREE( cmap->results ); + } + + + static FT_Error + tt_cmap14_ensure( TT_CMap14 cmap, + FT_UInt32 num_results, + FT_Memory memory ) + { + FT_UInt32 old_max = cmap->max_results; + FT_Error error = 0; + + + if ( num_results > cmap->max_results ) + { + cmap->memory = memory; + + if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) + return error; + + cmap->max_results = num_results; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_init( TT_CMap14 cmap, + FT_Byte* table ) + { + cmap->cmap.data = table; + + table += 6; + cmap->num_selectors = FT_PEEK_ULONG( table ); + cmap->max_results = 0; + cmap->results = NULL; + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_ULong length = TT_NEXT_ULONG( p ); + FT_ULong num_selectors = TT_NEXT_ULONG( p ); + + + if ( length > (FT_ULong)( valid->limit - table ) || + length < 10 + 11 * num_selectors ) + FT_INVALID_TOO_SHORT; + + /* check selectors, they must be in increasing order */ + { + /* we start lastVarSel at 1 because a variant selector value of 0 + * isn't valid. + */ + FT_ULong n, lastVarSel = 1; + + + for ( n = 0; n < num_selectors; n++ ) + { + FT_ULong varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( defOff >= length || nondefOff >= length ) + FT_INVALID_TOO_SHORT; + + if ( varSel < lastVarSel ) + FT_INVALID_DATA; + + lastVarSel = varSel + 1; + + /* check the default table (these glyphs should be reached */ + /* through the normal Unicode cmap, no GIDs, just check order) */ + if ( defOff != 0 ) + { + FT_Byte* defp = table + defOff; + FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_ULong i; + FT_ULong lastBase = 0; + + + if ( defp + numRanges * 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numRanges; ++i ) + { + FT_ULong base = TT_NEXT_UINT24( defp ); + FT_ULong cnt = FT_NEXT_BYTE( defp ); + + + if ( base + cnt >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( base < lastBase ) + FT_INVALID_DATA; + + lastBase = base + cnt + 1U; + } + } + + /* and the non-default table (these glyphs are specified here) */ + if ( nondefOff != 0 ) { + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings = TT_NEXT_ULONG( ndp ); + FT_ULong i, lastUni = 0; + + + if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; ++i ) + { + FT_ULong uni = TT_NEXT_UINT24( ndp ); + FT_ULong gid = TT_NEXT_USHORT( ndp ); + + + if ( uni >= 0x110000UL ) /* end of Unicode */ + FT_INVALID_DATA; + + if ( uni < lastUni ) + FT_INVALID_DATA; + + lastUni = uni + 1U; + + if ( valid->level >= FT_VALIDATE_TIGHT && + gid >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + + return SFNT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UNUSED( cmap ); + FT_UNUSED( char_code ); + + /* This can't happen */ + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap14_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UNUSED( cmap ); + + /* This can't happen */ + *pchar_code = 0; + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap14_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_UNUSED( cmap ); + + cmap_info->format = 14; + /* subtable 14 does not define a language field */ + cmap_info->language = 0xFFFFFFFFUL; + + return SFNT_Err_Ok; + } + + + static FT_UInt + tt_cmap14_char_map_def_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numRanges = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numRanges; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 4 * mid; + FT_ULong start = TT_NEXT_UINT24( p ); + FT_UInt cnt = FT_NEXT_BYTE( p ); + + + if ( char_code < start ) + max = mid; + else if ( char_code > start+cnt ) + min = mid + 1; + else + return TRUE; + } + + return FALSE; + } + + + static FT_UInt + tt_cmap14_char_map_nondef_binary( FT_Byte *base, + FT_UInt32 char_code ) + { + FT_UInt32 numMappings = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numMappings; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 5 * mid; + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + if ( char_code < uni ) + max = mid; + else if ( char_code > uni ) + min = mid + 1; + else + return TT_PEEK_USHORT( p ); + } + + return 0; + } + + + static FT_Byte* + tt_cmap14_find_variant( FT_Byte *base, + FT_UInt32 variantCode ) + { + FT_UInt32 numVar = TT_PEEK_ULONG( base ); + FT_UInt32 max, min; + + + min = 0; + max = numVar; + + base += 4; + + /* binary search */ + while ( min < max ) + { + FT_UInt32 mid = ( min + max ) >> 1; + FT_Byte* p = base + 11 * mid; + FT_ULong varSel = TT_NEXT_UINT24( p ); + + + if ( variantCode < varSel ) + max = mid; + else if ( variantCode > varSel ) + min = mid + 1; + else + return p; + } + + return NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap14_char_var_index( TT_CMap cmap, + TT_CMap ucmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return 0; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_PEEK_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + { + /* This is the default variant of this charcode. GID not stored */ + /* here; stored in the normal Unicode charmap instead. */ + return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); + } + + if ( nondefOff != 0 ) + return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ); + + return 0; + } + + + FT_CALLBACK_DEF( FT_Int ) + tt_cmap14_char_var_isdefault( TT_CMap cmap, + FT_UInt32 charcode, + FT_UInt32 variantSelector ) + { + FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return -1; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) + return 1; + + if ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charcode ) != 0 ) + return 0; + + return -1; + } + + + FT_CALLBACK_DEF( FT_UInt32* ) + tt_cmap14_variants( TT_CMap cmap, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14)cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* result; + FT_UInt32 i; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + result = cmap14->results; + for ( i = 0; i < count; ++i ) + { + result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 8; + } + result[i] = 0; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_char_variants( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 charCode ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 count = cmap14->num_selectors; + FT_Byte* p = cmap->data + 10; + FT_UInt32* q; + + + if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; count > 0; --count ) + { + FT_UInt32 varSel = TT_NEXT_UINT24( p ); + FT_ULong defOff = TT_NEXT_ULONG( p ); + FT_ULong nondefOff = TT_NEXT_ULONG( p ); + + + if ( ( defOff != 0 && + tt_cmap14_char_map_def_binary( cmap->data + defOff, + charCode ) ) || + ( nondefOff != 0 && + tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, + charCode ) != 0 ) ) + { + q[0] = varSel; + q++; + } + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt + tt_cmap14_def_char_count( FT_Byte *p ) + { + FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + FT_UInt tot = 0; + + + p += 3; /* point to the first `cnt' field */ + for ( ; numRanges > 0; numRanges-- ) + { + tot += 1 + p[0]; + p += 4; + } + + return tot; + } + + + static FT_UInt32* + tt_cmap14_get_def_chars( TT_CMap cmap, + FT_Byte* p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt cnt; + FT_UInt32* q; + + + cnt = tt_cmap14_def_char_count( p ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) + return NULL; + + for ( q = cmap14->results; numRanges > 0; --numRanges ) + { + FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); + + + cnt = FT_NEXT_BYTE( p ) + 1; + do + { + q[0] = uni; + uni += 1; + q += 1; + } while ( --cnt != 0 ); + } + q[0] = 0; + + return cmap14->results; + } + + + static FT_UInt32* + tt_cmap14_get_nondef_chars( TT_CMap cmap, + FT_Byte *p, + FT_Memory memory ) + { + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numMappings; + FT_UInt i; + FT_UInt32 *ret; + + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + + if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + for ( i = 0; i < numMappings; ++i ) + { + ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + ret[i] = 0; + + return ret; + } + + + FT_CALLBACK_DEF( FT_UInt32 * ) + tt_cmap14_variant_chars( TT_CMap cmap, + FT_Memory memory, + FT_UInt32 variantSelector ) + { + FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, + variantSelector ); + FT_UInt32 *ret; + FT_Int i; + FT_ULong defOff; + FT_ULong nondefOff; + + + if ( !p ) + return NULL; + + defOff = TT_NEXT_ULONG( p ); + nondefOff = TT_NEXT_ULONG( p ); + + if ( defOff == 0 && nondefOff == 0 ) + return NULL; + + if ( defOff == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + else if ( nondefOff == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + else + { + /* Both a default and a non-default glyph set? That's probably not */ + /* good font design, but the spec allows for it... */ + TT_CMap14 cmap14 = (TT_CMap14) cmap; + FT_UInt32 numRanges; + FT_UInt32 numMappings; + FT_UInt32 duni; + FT_UInt32 dcnt; + FT_UInt32 nuni; + FT_Byte* dp; + FT_UInt di, ni, k; + + + p = cmap->data + nondefOff; + dp = cmap->data + defOff; + + numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); + dcnt = tt_cmap14_def_char_count( dp ); + numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); + + if ( numMappings == 0 ) + return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, + memory ); + if ( dcnt == 0 ) + return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, + memory ); + + if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) + return NULL; + + ret = cmap14->results; + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + di = 1; + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ni = 1; + i = 0; + + for ( ;; ) + { + if ( nuni > duni + dcnt ) + { + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + ++di; + + if ( di > numRanges ) + break; + + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + } + else + { + if ( nuni < duni ) + ret[i++] = nuni; + /* If it is within the default range then ignore it -- */ + /* that should not have happened */ + ++ni; + if ( ni > numMappings ) + break; + + nuni = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + } + } + + if ( ni <= numMappings ) + { + /* If we get here then we have run out of all default ranges. */ + /* We have read one non-default mapping which we haven't stored */ + /* and there may be others that need to be read. */ + ret[i++] = nuni; + while ( ni < numMappings ) + { + ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); + p += 2; + ++ni; + } + } + else if ( di <= numRanges ) + { + /* If we get here then we have run out of all non-default */ + /* mappings. We have read one default range which we haven't */ + /* stored and there may be others that need to be read. */ + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + + while ( di < numRanges ) + { + duni = (FT_UInt32)TT_NEXT_UINT24( dp ); + dcnt = FT_NEXT_BYTE( dp ); + + for ( k = 0; k <= dcnt; ++k ) + ret[i++] = duni + k; + ++di; + } + } + + ret[i] = 0; + + return ret; + } + } + + + FT_DEFINE_TT_CMAP(tt_cmap14_class_rec, + sizeof ( TT_CMap14Rec ), + + (FT_CMap_InitFunc) tt_cmap14_init, + (FT_CMap_DoneFunc) tt_cmap14_done, + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, + (FT_CMap_CharNextFunc) tt_cmap14_char_next, + + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars + , + 14, + (TT_CMap_ValidateFunc)tt_cmap14_validate, + (TT_CMap_Info_GetFunc)tt_cmap14_get_info + ) + +#endif /* TT_CONFIG_CMAP_FORMAT_14 */ + + +#ifndef FT_CONFIG_OPTION_PIC + static const TT_CMap_Class tt_cmap_classes[] = { -#ifdef TT_CONFIG_CMAP_FORMAT_0 - &tt_cmap0_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_2 - &tt_cmap2_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_4 - &tt_cmap4_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_6 - &tt_cmap6_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_8 - &tt_cmap8_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_10 - &tt_cmap10_class_rec, -#endif - -#ifdef TT_CONFIG_CMAP_FORMAT_12 - &tt_cmap12_class_rec, -#endif - +#define TTCMAPCITEM(a) &a, +#include "ttcmapc.h" NULL, }; +#else /*FT_CONFIG_OPTION_PIC*/ + + void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz) + { + FT_Memory memory = library->memory; + if ( clazz ) + FT_FREE( clazz ); + } + + FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class) + { + TT_CMap_Class* clazz; + TT_CMap_ClassRec* recs; + FT_Error error; + FT_Memory memory = library->memory; + int i = 0; + +#define TTCMAPCITEM(a) i++; +#include "ttcmapc.h" + + /* allocate enough space for both the pointers +terminator and the class instances */ + if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) ) + return error; + + /* the location of the class instances follows the array of pointers */ + recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); + i=0; + +#undef TTCMAPCITEM +#define TTCMAPCITEM(a) \ + FT_Init_Class_##a(&recs[i]); \ + clazz[i] = &recs[i]; \ + i++; +#include "ttcmapc.h" + + clazz[i] = NULL; + + *output_class = clazz; + return FT_Err_Ok; + } + +#endif /*FT_CONFIG_OPTION_PIC*/ + /* parse the `cmap' table and build the corresponding TT_CMap objects */ /* in the current face */ @@ -2256,6 +3391,8 @@ FT_Byte* limit = table + face->cmap_size; FT_UInt volatile num_cmaps; FT_Byte* volatile p = table; + FT_Library library = FT_FACE_LIBRARY(face); + FT_UNUSED(library); if ( p + 4 > limit ) @@ -2265,7 +3402,8 @@ if ( TT_NEXT_USHORT( p ) != 0 ) { p -= 2; - FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", + FT_ERROR(( "tt_face_build_cmaps:" + " unsupported `cmap' table format = %d\n", TT_PEEK_USHORT( p ) )); return SFNT_Err_Invalid_Table; } @@ -2288,7 +3426,7 @@ { FT_Byte* volatile cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); - const TT_CMap_Class* volatile pclazz = tt_cmap_classes; + const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET; TT_CMap_Class volatile clazz; @@ -2318,6 +3456,10 @@ FT_CMap ttcmap; + /* It might make sense to store the single variation selector */ + /* cmap somewhere special. But it would have to be in the */ + /* public FT_FaceRec, and we can't change that. */ + if ( !FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, &ttcmap ) ) { @@ -2328,12 +3470,18 @@ } else { - FT_ERROR(( "tt_face_build_cmaps:" )); - FT_ERROR(( " broken cmap sub-table ignored!\n" )); + FT_TRACE0(( "tt_face_build_cmaps:" + " broken cmap sub-table ignored\n" )); } break; } } + + if ( *pclazz == NULL ) + { + FT_TRACE0(( "tt_face_build_cmaps:" + " unsupported cmap sub-table ignored\n" )); + } } } diff --git a/lib/3rdparty/freetype/src/sfnt/ttcmap.h b/lib/3rdparty/freetype/src/sfnt/ttcmap.h index a10a3e2502c..15a4a21e500 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttcmap.h +++ b/lib/3rdparty/freetype/src/sfnt/ttcmap.h @@ -55,6 +55,46 @@ FT_BEGIN_HEADER } TT_CMap_ClassRec; +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + FT_CALLBACK_TABLE_DEF \ + const TT_CMap_ClassRec class_ = \ + { \ + {size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_, variantchar_list_}, \ + format_, validate_, get_cmap_info_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_, \ + char_next_, char_var_index_, char_var_default_, variant_list_, \ + charvariant_list_,variantchar_list_, \ + format_, validate_, get_cmap_info_) \ + void \ + FT_Init_Class_##class_( TT_CMap_ClassRec* clazz ) \ + { \ + clazz->clazz.size = size_; \ + clazz->clazz.init = init_; \ + clazz->clazz.done = done_; \ + clazz->clazz.char_index = char_index_; \ + clazz->clazz.char_next = char_next_; \ + clazz->clazz.char_var_index = char_var_index_; \ + clazz->clazz.char_var_default = char_var_default_; \ + clazz->clazz.variant_list = variant_list_; \ + clazz->clazz.charvariant_list = charvariant_list_; \ + clazz->clazz.variantchar_list = variantchar_list_; \ + clazz->format = format_; \ + clazz->validate = validate_; \ + clazz->get_cmap_info = get_cmap_info_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ typedef struct TT_ValidatorRec_ { diff --git a/lib/3rdparty/freetype/src/sfnt/ttcmapc.h b/lib/3rdparty/freetype/src/sfnt/ttcmapc.h new file mode 100644 index 00000000000..4c9c6a56f72 --- /dev/null +++ b/lib/3rdparty/freetype/src/sfnt/ttcmapc.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttcmapc.h */ +/* */ +/* TT CMAP classes definitions (specification only). */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + TTCMAPCITEM(tt_cmap0_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + TTCMAPCITEM(tt_cmap2_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + TTCMAPCITEM(tt_cmap4_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + TTCMAPCITEM(tt_cmap6_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + TTCMAPCITEM(tt_cmap8_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + TTCMAPCITEM(tt_cmap10_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + TTCMAPCITEM(tt_cmap12_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_13 + TTCMAPCITEM(tt_cmap13_class_rec) +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_14 + TTCMAPCITEM(tt_cmap14_class_rec) +#endif + + /* END */ diff --git a/lib/3rdparty/freetype/src/sfnt/ttkern.c b/lib/3rdparty/freetype/src/sfnt/ttkern.c index 28e52c333e8..c1540802b87 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttkern.c +++ b/lib/3rdparty/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttkern.h" -#include "ttload.h" #include "sferrors.h" @@ -60,14 +59,16 @@ if ( table_size < 4 ) /* the case of a malformed table */ { - FT_ERROR(( "kerning table is too small - ignored\n" )); + FT_ERROR(( "tt_face_load_kern:" + " kerning table is too small - ignored\n" )); error = SFNT_Err_Table_Missing; goto Exit; } if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) ) { - FT_ERROR(( "could not extract kerning table\n" )); + FT_ERROR(( "tt_face_load_kern:" + " could not extract kerning table\n" )); goto Exit; } @@ -86,7 +87,7 @@ { FT_UInt num_pairs, length, coverage; FT_Byte* p_next; - FT_UInt32 mask = 1UL << nn; + FT_UInt32 mask = (FT_UInt32)1UL << nn; if ( p + 6 > p_limit ) @@ -103,6 +104,9 @@ p_next += length; + if ( p_next > p_limit ) /* handle broken table */ + p_next = p_limit; + /* only use horizontal kerning tables */ if ( ( coverage & ~8 ) != 0x0001 || p + 8 > p_limit ) @@ -111,8 +115,8 @@ num_pairs = FT_NEXT_USHORT( p ); p += 6; - if ( p + 6 * num_pairs > p_limit ) - goto NextTable; + if ( ( p_next - p ) / 6 < (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( p_next - p ) / 6 ); avail |= mask; @@ -122,8 +126,8 @@ */ if ( num_pairs > 0 ) { - FT_UInt count; - FT_UInt old_pair; + FT_ULong count; + FT_ULong old_pair; old_pair = FT_NEXT_ULONG( p ); @@ -181,18 +185,22 @@ FT_Int result = 0; FT_UInt count, mask = 1; FT_Byte* p = face->kern_table; + FT_Byte* p_limit = p + face->kern_table_size; p += 4; mask = 0x0001; - for ( count = face->num_kern_tables; count > 0; count--, mask <<= 1 ) + for ( count = face->num_kern_tables; + count > 0 && p + 6 <= p_limit; + count--, mask <<= 1 ) { FT_Byte* base = p; FT_Byte* next = base; FT_UInt version = FT_NEXT_USHORT( p ); FT_UInt length = FT_NEXT_USHORT( p ); FT_UInt coverage = FT_NEXT_USHORT( p ); + FT_UInt num_pairs; FT_Int value = 0; FT_UNUSED( version ); @@ -200,22 +208,28 @@ next = base + length; + if ( next > p_limit ) /* handle broken table */ + next = p_limit; + if ( ( face->kern_avail_bits & mask ) == 0 ) goto NextTable; if ( p + 8 > next ) goto NextTable; + num_pairs = FT_NEXT_USHORT( p ); + p += 6; + + if ( ( next - p ) / 6 < (int)num_pairs ) /* handle broken count */ + num_pairs = (FT_UInt)( ( next - p ) / 6 ); + switch ( coverage >> 8 ) { case 0: { - FT_UInt num_pairs = FT_NEXT_USHORT( p ); - FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); + FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph ); - p += 6; - if ( face->kern_order_bits & mask ) /* binary search */ { FT_UInt min = 0; diff --git a/lib/3rdparty/freetype/src/sfnt/ttload.c b/lib/3rdparty/freetype/src/sfnt/ttload.c index abe0278a253..3ad33bd6d86 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttload.c +++ b/lib/3rdparty/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,6 +58,9 @@ { TT_Table entry; TT_Table limit; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool zero_length = FALSE; +#endif FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", @@ -72,17 +75,28 @@ for ( ; entry < limit; entry++ ) { - /* For compatibility with Windows, we consider 0-length */ - /* tables the same as missing tables. */ - if ( entry->Tag == tag && entry->Length != 0 ) - { - FT_TRACE4(( "found table.\n" )); - return entry; + /* For compatibility with Windows, we consider */ + /* zero-length tables the same as missing tables. */ + if ( entry->Tag == tag ) { + if ( entry->Length != 0 ) + { + FT_TRACE4(( "found table.\n" )); + return entry; + } +#ifdef FT_DEBUG_LEVEL_TRACE + zero_length = TRUE; +#endif } } - FT_TRACE4(( "could not find table!\n" )); - return 0; +#ifdef FT_DEBUG_LEVEL_TRACE + if ( zero_length ) + FT_TRACE4(( "ignoring empty table\n" )); + else + FT_TRACE4(( "could not find table\n" )); +#endif + + return NULL; } @@ -124,7 +138,7 @@ *length = table->Length; if ( FT_STREAM_SEEK( table->Offset ) ) - goto Exit; + goto Exit; } else error = SFNT_Err_Table_Missing; @@ -134,27 +148,30 @@ } - /* Here, we */ - /* */ - /* - check that `num_tables' is valid */ - /* - look for a `head' table, check its size, and parse it to check */ - /* whether its `magic' field is correctly set */ - /* */ - /* When checking directory entries, ignore the tables `glyx' and `locx' */ - /* which are hacked-out versions of `glyf' and `loca' in some PostScript */ - /* Type 42 fonts, and which are generally invalid. */ - /* */ + /* Here, we */ + /* */ + /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* */ + /* - look for a `head' table, check its size, and parse it to check */ + /* whether its `magic' field is correctly set */ + /* */ + /* - errors (except errors returned by stream handling) */ + /* */ + /* SFNT_Err_Unknown_File_Format: */ + /* no table is defined in directory, it is not sfnt-wrapped */ + /* data */ + /* SFNT_Err_Table_Missing: */ + /* table directory is valid, but essential tables */ + /* (head/bhed/SING) are missing */ + /* */ static FT_Error check_table_dir( SFNT_Header sfnt, FT_Stream stream ) { - FT_Error error; - FT_UInt nn; - FT_UInt has_head = 0, has_sing = 0, has_meta = 0; - FT_ULong offset = sfnt->offset + 12; - - const FT_ULong glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' ); - const FT_ULong locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' ); + FT_Error error; + FT_UShort nn, valid_entries = 0; + FT_UInt has_head = 0, has_sing = 0, has_meta = 0; + FT_ULong offset = sfnt->offset + 12; static const FT_Frame_Field table_dir_entry_fields[] = { @@ -170,12 +187,8 @@ }; - if ( sfnt->num_tables == 0 || - offset + sfnt->num_tables * 16 > stream->size ) - return SFNT_Err_Unknown_File_Format; - if ( FT_STREAM_SEEK( offset ) ) - return error; + goto Exit; for ( nn = 0; nn < sfnt->num_tables; nn++ ) { @@ -183,12 +196,23 @@ if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) ) - return error; + { + nn--; + FT_TRACE2(( "check_table_dir:" + " can read only %d table%s in font (instead of %d)\n", + nn, nn == 1 ? "" : "s", sfnt->num_tables )); + sfnt->num_tables = nn; + break; + } - if ( table.Offset + table.Length > stream->size && - table.Tag != glyx_tag && - table.Tag != locx_tag ) - return SFNT_Err_Unknown_File_Format; + /* we ignore invalid tables */ + if ( table.Offset + table.Length > stream->size ) + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + else + valid_entries++; if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) { @@ -210,17 +234,26 @@ * */ if ( table.Length < 0x36 ) - return SFNT_Err_Unknown_File_Format; + { + FT_TRACE2(( "check_table_dir: `head' table too small\n" )); + error = SFNT_Err_Table_Missing; + goto Exit; + } if ( FT_STREAM_SEEK( table.Offset + 12 ) || FT_READ_ULONG( magic ) ) - return error; + goto Exit; if ( magic != 0x5F0F3CF5UL ) - return SFNT_Err_Unknown_File_Format; + { + FT_TRACE2(( "check_table_dir:" + " no magic number found in `head' table\n")); + error = SFNT_Err_Table_Missing; + goto Exit; + } if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) - return error; + goto Exit; } else if ( table.Tag == TTAG_SING ) has_sing = 1; @@ -228,11 +261,34 @@ has_meta = 1; } + sfnt->num_tables = valid_entries; + + if ( sfnt->num_tables == 0 ) + { + FT_TRACE2(( "check_table_dir: no tables found\n" )); + error = SFNT_Err_Unknown_File_Format; + goto Exit; + } + /* if `sing' and `meta' tables are present, there is no `head' table */ if ( has_head || ( has_sing && has_meta ) ) - return SFNT_Err_Ok; + { + error = SFNT_Err_Ok; + goto Exit; + } else - return SFNT_Err_Unknown_File_Format; + { + FT_TRACE2(( "check_table_dir:" )); +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" )); +#else + FT_TRACE2(( " neither `head' nor `sing' table found\n" )); +#endif + error = SFNT_Err_Table_Missing; + } + + Exit: + return error; } @@ -266,7 +322,7 @@ FT_Error error; FT_Memory memory = stream->memory; TT_TableRec* entry; - TT_TableRec* limit; + FT_Int nn; static const FT_Frame_Field offset_table_fields[] = { @@ -290,7 +346,7 @@ if ( FT_READ_ULONG( sfnt.format_tag ) || FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) ) - return error; + goto Exit; /* many fonts don't have these fields set correctly */ #if 0 @@ -301,51 +357,59 @@ /* load the table directory */ - FT_TRACE2(( "-- Tables count: %12u\n", sfnt.num_tables )); - FT_TRACE2(( "-- Format version: %08lx\n", sfnt.format_tag )); + FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); + FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); /* check first */ error = check_table_dir( &sfnt, stream ); if ( error ) { - FT_TRACE2(( "tt_face_load_font_dir: invalid table directory!\n" )); + FT_TRACE2(( "tt_face_load_font_dir:" + " invalid table directory for TrueType\n" )); - return error; + goto Exit; } face->num_tables = sfnt.num_tables; face->format_tag = sfnt.format_tag; if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) - return error; + goto Exit; if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || FT_FRAME_ENTER( face->num_tables * 16L ) ) - return error; + goto Exit; entry = face->dir_tables; - limit = entry + face->num_tables; - for ( ; entry < limit; entry++ ) + for ( nn = 0; nn < sfnt.num_tables; nn++ ) { entry->Tag = FT_GET_TAG4(); entry->CheckSum = FT_GET_ULONG(); entry->Offset = FT_GET_LONG(); entry->Length = FT_GET_LONG(); - FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length )); + /* ignore invalid tables */ + if ( entry->Offset + entry->Length > stream->size ) + continue; + else + { + FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", + (FT_Char)( entry->Tag >> 24 ), + (FT_Char)( entry->Tag >> 16 ), + (FT_Char)( entry->Tag >> 8 ), + (FT_Char)( entry->Tag ), + entry->Offset, + entry->Length )); + entry++; + } } FT_FRAME_EXIT(); FT_TRACE2(( "table directory loaded\n\n" )); + Exit: return error; } @@ -618,6 +682,17 @@ if ( maxProfile->maxFunctionDefs == 0 ) maxProfile->maxFunctionDefs = 64; + + /* we add 4 phantom points later */ + if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) + { + FT_TRACE0(( "tt_face_load_maxp:" + " too much twilight points in `maxp' table;\n" + " " + " some glyphs might be rendered incorrectly\n" )); + + maxProfile->maxTwilightPoints = 0xFFFFU - 4; + } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); @@ -707,7 +782,7 @@ if ( storage_start > storage_limit ) { - FT_ERROR(( "invalid `name' table\n" )); + FT_ERROR(( "tt_face_load_name: invalid `name' table\n" )); error = SFNT_Err_Name_Table_Missing; goto Exit; } diff --git a/lib/3rdparty/freetype/src/sfnt/ttmtx.c b/lib/3rdparty/freetype/src/sfnt/ttmtx.c index 286bd0c311c..53e6ac7881f 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttmtx.c +++ b/lib/3rdparty/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -60,7 +60,7 @@ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL_DEF( FT_Error ) tt_face_load_hmtx( TT_Face face, @@ -97,7 +97,7 @@ return error; } -#else /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ FT_LOCAL_DEF( FT_Error ) tt_face_load_hmtx( TT_Face face, @@ -161,7 +161,9 @@ if ( num_shorts < 0 ) { - FT_ERROR(( "%cmtx has more metrics than glyphs.\n" )); + FT_TRACE0(( "tt_face_load_hmtx:" + " %cmtx has more metrics than glyphs.\n", + vertical ? "v" : "h" )); /* Adobe simply ignores this problem. So we shall do the same. */ #if 0 @@ -229,7 +231,7 @@ return error; } -#endif /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ /*************************************************************************/ @@ -341,7 +343,7 @@ /* */ /* advance :: The advance width resp. advance height. */ /* */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face, @@ -420,7 +422,7 @@ return SFNT_Err_Ok; } -#else /* OLD_INTERNALS */ +#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face, @@ -431,7 +433,8 @@ { void* v = &face->vertical; void* h = &face->horizontal; - TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v : h; + TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v + : (TT_HoriHeader*)h; TT_LongMetrics longs_m; FT_UShort k = header->number_Of_HMetrics; @@ -459,7 +462,7 @@ return SFNT_Err_Ok; } -#endif /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ /* END */ diff --git a/lib/3rdparty/freetype/src/sfnt/ttpost.c b/lib/3rdparty/freetype/src/sfnt/ttpost.c index 1e6163646dc..aa0bf1ec419 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttpost.c +++ b/lib/3rdparty/freetype/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttpost.h" -#include "ttload.h" #include "sferrors.h" @@ -62,11 +61,11 @@ /* table of Mac names. Thus, it is possible to build a version of */ /* FreeType without the Type 1 driver & PSNames module. */ -#define MAC_NAME( x ) tt_post_default_names[x] +#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) /* the 258 default Mac PS glyph names */ - static const FT_String* tt_post_default_names[258] = + static const FT_String* const tt_post_default_names[258] = { /* 0 */ ".notdef", ".null", "CR", "space", "exclam", @@ -416,13 +415,14 @@ /* tt_face_get_ps_name */ /* */ /* <Description> */ - /* Gets the PostScript glyph name of a glyph. */ + /* Get the PostScript glyph name of a glyph. */ /* */ /* <Input> */ /* face :: A handle to the parent face. */ /* */ /* idx :: The glyph index. */ /* */ + /* <InOut> */ /* PSname :: The address of a string pointer. Will be NULL in case */ /* of error, otherwise it is a pointer to the glyph name. */ /* */ @@ -436,9 +436,9 @@ FT_UInt idx, FT_String** PSname ) { - FT_Error error; - TT_Post_Names names; - FT_Fixed format; + FT_Error error; + TT_Post_Names names; + FT_Fixed format; #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_Service_PsCMaps psnames; diff --git a/lib/3rdparty/freetype/src/sfnt/ttsbit.c b/lib/3rdparty/freetype/src/sfnt/ttsbit.c index eff49dadd9a..833bb2add29 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttsbit.c +++ b/lib/3rdparty/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,11 +24,11 @@ * Alas, the memory-optimized sbit loader can't be used when implementing * the `old internals' hack */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS #include "ttsbit0.c" -#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ +#else /* FT_CONFIG_OPTION_OLD_INTERNALS */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H @@ -83,7 +83,8 @@ FT_Int line_bits, FT_Bool byte_padded, FT_Int x_offset, - FT_Int y_offset ) + FT_Int y_offset, + FT_Int source_height ) { FT_Byte* line_buff; FT_Int line_incr; @@ -116,7 +117,7 @@ acc = 0; /* clear accumulator */ loaded = 0; /* no bits were loaded */ - for ( height = target->rows; height > 0; height-- ) + for ( height = source_height; height > 0; height-- ) { FT_Byte* cur = line_buff; /* current write cursor */ FT_Int count = line_bits; /* # of bits to extract per line */ @@ -382,8 +383,9 @@ break; case 5: - error = Load_SBit_Const_Metrics( range, stream ) || - Load_SBit_Range_Codes( range, stream, 0 ); + error = Load_SBit_Const_Metrics( range, stream ); + if ( !error ) + error = Load_SBit_Range_Codes( range, stream, 0 ); break; default: @@ -492,7 +494,7 @@ if ( version != 0x00020000L || num_strikes >= 0x10000L ) { - FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; @@ -771,7 +773,7 @@ Found: /* return successfully! */ *arange = range; - return 0; + return SFNT_Err_Ok; } } @@ -1229,7 +1231,7 @@ /* the sbit blitter doesn't make a difference between pixmap */ /* depths. */ blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes, - x_offset * pix_bits, y_offset ); + x_offset * pix_bits, y_offset, metrics->height ); FT_FRAME_EXIT(); } @@ -1323,7 +1325,11 @@ range->image_format, metrics, stream ); case 8: /* compound format */ - FT_Stream_Skip( stream, 1L ); + if ( FT_STREAM_SKIP( 1L ) ) + { + error = SFNT_Err_Invalid_Stream_Skip; + goto Exit; + } /* fallthrough */ case 9: @@ -1495,7 +1501,7 @@ return error; } -#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ /* END */ diff --git a/lib/3rdparty/freetype/src/sfnt/ttsbit.h b/lib/3rdparty/freetype/src/sfnt/ttsbit.h index c6067c0e3e6..7ea2af18436 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttsbit.h +++ b/lib/3rdparty/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_ULong strike_index, FT_Size_Metrics* metrics ); -#if defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS FT_LOCAL( FT_Error ) tt_find_sbit_image( TT_Face face, FT_UInt glyph_index, diff --git a/lib/3rdparty/freetype/src/sfnt/ttsbit0.c b/lib/3rdparty/freetype/src/sfnt/ttsbit0.c index f8adc64a735..38bcf210ead 100644 --- a/lib/3rdparty/freetype/src/sfnt/ttsbit0.c +++ b/lib/3rdparty/freetype/src/sfnt/ttsbit0.c @@ -5,7 +5,7 @@ /* TrueType and OpenType embedded bitmap support (body). */ /* This is a heap-optimized version. */ /* */ -/* Copyright 2005, 2006, 2007 by */ +/* Copyright 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,65 +39,16 @@ #define FT_COMPONENT trace_ttsbit - static const FT_Frame_Field tt_sbit_line_metrics_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_SBit_LineMetricsRec - - /* no FT_FRAME_START */ - FT_FRAME_CHAR( ascender ), - FT_FRAME_CHAR( descender ), - FT_FRAME_BYTE( max_width ), - - FT_FRAME_CHAR( caret_slope_numerator ), - FT_FRAME_CHAR( caret_slope_denominator ), - FT_FRAME_CHAR( caret_offset ), - - FT_FRAME_CHAR( min_origin_SB ), - FT_FRAME_CHAR( min_advance_SB ), - FT_FRAME_CHAR( max_before_BL ), - FT_FRAME_CHAR( min_after_BL ), - FT_FRAME_CHAR( pads[0] ), - FT_FRAME_CHAR( pads[1] ), - FT_FRAME_END - }; - - static const FT_Frame_Field tt_strike_start_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE TT_SBit_StrikeRec - - /* no FT_FRAME_START */ - FT_FRAME_ULONG( ranges_offset ), - FT_FRAME_SKIP_LONG, - FT_FRAME_ULONG( num_ranges ), - FT_FRAME_ULONG( color_ref ), - FT_FRAME_END - }; - - static const FT_Frame_Field tt_strike_end_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_USHORT( start_glyph ), - FT_FRAME_USHORT( end_glyph ), - FT_FRAME_BYTE ( x_ppem ), - FT_FRAME_BYTE ( y_ppem ), - FT_FRAME_BYTE ( bit_depth ), - FT_FRAME_CHAR ( flags ), - FT_FRAME_END - }; - - FT_LOCAL_DEF( FT_Error ) tt_face_load_eblc( TT_Face face, FT_Stream stream ) { - FT_Error error = SFNT_Err_Ok; - FT_Fixed version; - FT_ULong num_strikes, table_size; - FT_Byte* p; - FT_Byte* p_limit; - FT_UInt count; + FT_Error error = SFNT_Err_Ok; + FT_Fixed version; + FT_ULong num_strikes, table_size; + FT_Byte* p; + FT_Byte* p_limit; + FT_UInt count; face->sbit_num_strikes = 0; @@ -111,7 +62,7 @@ if ( table_size < 8 ) { - FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" )); + FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; } @@ -129,8 +80,7 @@ if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) { - FT_ERROR(( "%s: invalid table version!\n", - "tt_face_load_sbit_strikes" )); + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); error = SFNT_Err_Invalid_File_Format; goto Fail; } @@ -182,7 +132,7 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - FT_Byte* strike; + FT_Byte* strike; if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) @@ -207,7 +157,7 @@ } - typedef struct + typedef struct TT_SBitDecoderRec_ { TT_Face face; FT_Stream stream; @@ -374,14 +324,11 @@ if ( p + 5 > limit ) goto Fail; - if ( !decoder->metrics_loaded ) - { - metrics->height = p[0]; - metrics->width = p[1]; - metrics->horiBearingX = (FT_Char)p[2]; - metrics->horiBearingY = (FT_Char)p[3]; - metrics->horiAdvance = p[4]; - } + metrics->height = p[0]; + metrics->width = p[1]; + metrics->horiBearingX = (FT_Char)p[2]; + metrics->horiBearingY = (FT_Char)p[3]; + metrics->horiAdvance = p[4]; p += 5; if ( big ) @@ -389,19 +336,16 @@ if ( p + 3 > limit ) goto Fail; - if ( !decoder->metrics_loaded ) - { - metrics->vertBearingX = (FT_Char)p[0]; - metrics->vertBearingY = (FT_Char)p[1]; - metrics->vertAdvance = p[2]; - } + metrics->vertBearingX = (FT_Char)p[0]; + metrics->vertBearingY = (FT_Char)p[1]; + metrics->vertAdvance = p[2]; p += 3; } decoder->metrics_loaded = 1; *pp = p; - return 0; + return SFNT_Err_Ok; Fail: return SFNT_Err_Invalid_Argument; @@ -507,7 +451,7 @@ if ( w > 0 ) wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); - /* all bits read and there are ( x_pos + w ) bits to be written */ + /* all bits read and there are `x_pos + w' bits to be written */ write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); @@ -525,6 +469,41 @@ } + /* + * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap + * (with pointer `write'). In the example below, the width is 3 pixel, + * and `x_pos' is 1 pixel. + * + * p p+1 + * | | | + * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... + * | | | + * +-------+ +-------+ +-------+ ... + * . . . + * . . . + * v . . + * +-------+ . . + * | | . + * | 7 6 5 4 3 2 1 0 | . + * | | . + * write . . + * . . + * v . + * +-------+ . + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+1 . + * . + * v + * +-------+ + * | | + * | 7 6 5 4 3 2 1 0 | + * | | + * write+2 + * + */ + static FT_Error tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, FT_Byte* p, @@ -570,6 +549,8 @@ } /* now do the blit */ + + /* adjust `line' to point to the first byte of the bitmap */ line += y_pos * pitch + ( x_pos >> 3 ); x_pos &= 7; @@ -580,16 +561,23 @@ for ( h = height; h > 0; h--, line += pitch ) { FT_Byte* write = line; - FT_Int w = width; + FT_Int w = width; + /* handle initial byte (in target bitmap) specially if necessary */ if ( x_pos ) { w = ( width < 8 - x_pos ) ? width : 8 - x_pos; - if ( nbits < w ) + if ( h == height ) { - rval |= *p++; + rval = *p++; + nbits = x_pos; + } + else if ( nbits < w ) + { + if ( p < limit ) + rval |= *p++; nbits += 8 - w; } else @@ -598,12 +586,14 @@ nbits -= w; } - *write++ |= ( ( rval >> nbits ) & 0xFF ) & ~( 0xFF << w ); + *write++ |= ( ( rval >> nbits ) & 0xFF ) & + ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); rval <<= 8; w = width - w; } + /* handle medial bytes */ for ( ; w >= 8; w -= 8 ) { rval |= *p++; @@ -612,11 +602,13 @@ rval <<= 8; } + /* handle final byte if necessary */ if ( w > 0 ) { if ( nbits < w ) { - rval |= *p++; + if ( p < limit ) + rval |= *p++; *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); nbits += 8 - w; @@ -645,6 +637,13 @@ FT_Error error = SFNT_Err_Ok; FT_UInt num_components, nn; + FT_Char horiBearingX = decoder->metrics->horiBearingX; + FT_Char horiBearingY = decoder->metrics->horiBearingY; + FT_Byte horiAdvance = decoder->metrics->horiAdvance; + FT_Char vertBearingX = decoder->metrics->vertBearingX; + FT_Char vertBearingY = decoder->metrics->vertBearingY; + FT_Byte vertAdvance = decoder->metrics->vertAdvance; + if ( p + 2 > limit ) goto Fail; @@ -653,6 +652,13 @@ if ( p + 4 * num_components > limit ) goto Fail; + if ( !decoder->bitmap_allocated ) + { + error = tt_sbit_decoder_alloc_bitmap( decoder ); + if ( error ) + goto Exit; + } + for ( nn = 0; nn < num_components; nn++ ) { FT_UInt gindex = FT_NEXT_USHORT( p ); @@ -667,6 +673,15 @@ break; } + decoder->metrics->horiBearingX = horiBearingX; + decoder->metrics->horiBearingY = horiBearingY; + decoder->metrics->horiAdvance = horiAdvance; + decoder->metrics->vertBearingX = vertBearingX; + decoder->metrics->vertBearingY = vertBearingY; + decoder->metrics->vertAdvance = vertAdvance; + decoder->metrics->width = (FT_UInt)decoder->bitmap->width; + decoder->metrics->height = (FT_UInt)decoder->bitmap->rows; + Exit: return error; diff --git a/lib/3rdparty/freetype/src/smooth/Jamfile b/lib/3rdparty/freetype/src/smooth/Jamfile index 8a792df056c..a8496aa2c2c 100644 --- a/lib/3rdparty/freetype/src/smooth/Jamfile +++ b/lib/3rdparty/freetype/src/smooth/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; if $(FT2_MULTI) { - _sources = ftgrays ftsmooth ; + _sources = ftgrays ftsmooth ftspic ; } else { diff --git a/lib/3rdparty/freetype/src/smooth/ftgrays.c b/lib/3rdparty/freetype/src/smooth/ftgrays.c index 5a4a544e5a5..846e454e667 100644 --- a/lib/3rdparty/freetype/src/smooth/ftgrays.c +++ b/lib/3rdparty/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -91,11 +91,19 @@ #define FT_COMPONENT trace_smooth - - #ifdef _STANDALONE_ -#include <string.h> /* for ft_memcpy() */ + + /* define this to dump debugging information */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + +#ifdef FT_DEBUG_LEVEL_TRACE +#include <stdio.h> +#include <stdarg.h> +#endif + +#include <string.h> #include <setjmp.h> #include <limits.h> #define FT_UINT_MAX UINT_MAX @@ -118,24 +126,81 @@ #include "ftimage.h" #include "ftgrays.h" + /* This macro is used to indicate that a function parameter is unused. */ /* Its purpose is simply to reduce compiler warnings. Note also that */ /* simply defining it as `(void)x' doesn't avoid warnings with certain */ /* ANSI compilers (e.g. LCC). */ #define FT_UNUSED( x ) (x) = (x) - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these two macros. */ + + /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ + +#ifdef FT_DEBUG_LEVEL_TRACE + + void + FT_Message( const char* fmt, + ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } + + /* we don't handle tracing levels in stand-alone mode; */ +#ifndef FT_TRACE5 +#define FT_TRACE5( varformat ) FT_Message varformat +#endif +#ifndef FT_TRACE7 +#define FT_TRACE7( varformat ) FT_Message varformat +#endif #ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ +#define FT_ERROR( varformat ) FT_Message varformat #endif -#ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#endif +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ +#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ +#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +#define FT_DEFINE_OUTLINE_FUNCS( class_, \ + move_to_, line_to_, \ + conic_to_, cubic_to_, \ + shift_, delta_ ) \ + static const FT_Outline_Funcs class_ = \ + { \ + move_to_, \ + line_to_, \ + conic_to_, \ + cubic_to_, \ + shift_, \ + delta_ \ + }; + +#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \ + raster_new_, raster_reset_, \ + raster_set_mode_, raster_render_, \ + raster_done_ ) \ + const FT_Raster_Funcs class_ = \ + { \ + glyph_format_, \ + raster_new_, \ + raster_reset_, \ + raster_set_mode_, \ + raster_render_, \ + raster_done_ \ + }; #else /* !_STANDALONE_ */ + #include <ft2build.h> #include "ftgrays.h" #include FT_INTERNAL_OBJECTS_H @@ -144,14 +209,15 @@ #include "ftsmerrs.h" -#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph -#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline -#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#define ErrRaster_Invalid_Argument Smooth_Err_Bad_Argument +#include "ftspic.h" + +#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph +#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline +#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory +#define ErrRaster_Invalid_Argument Smooth_Err_Invalid_Argument #endif /* !_STANDALONE_ */ - #ifndef FT_MEM_SET #define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) #endif @@ -160,35 +226,23 @@ #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) #endif - /* define this to dump debugging information */ -#define xxxDEBUG_GRAYS - - /* as usual, for the speed hungry :-) */ #ifndef FT_STATIC_RASTER - #define RAS_ARG PWorker worker #define RAS_ARG_ PWorker worker, #define RAS_VAR worker #define RAS_VAR_ worker, -#define ras (*worker) - - #else /* FT_STATIC_RASTER */ - #define RAS_ARG /* empty */ #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ - static TWorker ras; - - #endif /* FT_STATIC_RASTER */ @@ -221,7 +275,7 @@ /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef long TCoord; /* integer scanline/pixel coordinate */ typedef long TPos; /* sub-pixel coordinate */ /* determine the type used to store cell areas. This normally takes at */ @@ -252,8 +306,8 @@ typedef struct TCell_ { - int x; - int cover; + TPos x; /* same with TWorker.ex */ + TCoord cover; /* same with TWorker.cover */ TArea area; PCell next; @@ -268,12 +322,12 @@ TPos count_ex, count_ey; TArea area; - int cover; + TCoord cover; int invalid; PCell cells; - int max_cells; - int num_cells; + FT_PtrDist max_cells; + FT_PtrDist num_cells; TCoord cx, cy; TPos x, y; @@ -305,11 +359,18 @@ long buffer_size; PCell* ycells; - int ycount; + TPos ycount; } TWorker, *PWorker; +#ifndef FT_STATIC_RASTER +#define ras (*worker) +#else + static TWorker ras; +#endif + + typedef struct TRaster_ { void* buffer; @@ -395,11 +456,11 @@ gray_find_cell( RAS_ARG ) { PCell *pcell, cell; - int x = ras.ex; + TPos x = ras.ex; - if ( x > ras.max_ex ) - x = ras.max_ex; + if ( x > ras.count_ex ) + x = ras.count_ex; pcell = &ras.ycells[ras.ey]; for (;;) @@ -527,9 +588,9 @@ TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta; + TCoord ex1, ex2, fx1, fx2, delta, mod, lift, rem; long p, first, dx; - int incr, lift, mod, rem; + int incr; dx = x2 - x1; @@ -551,7 +612,7 @@ if ( ex1 == ex2 ) { delta = y2 - y1; - ras.area += (TArea)( fx1 + fx2 ) * delta; + ras.area += (TArea)(( fx1 + fx2 ) * delta); ras.cover += delta; return; } @@ -579,7 +640,7 @@ mod += (TCoord)dx; } - ras.area += (TArea)( fx1 + first ) * delta; + ras.area += (TArea)(( fx1 + first ) * delta); ras.cover += delta; ex1 += incr; @@ -609,7 +670,7 @@ delta++; } - ras.area += (TArea)ONE_PIXEL * delta; + ras.area += (TArea)(ONE_PIXEL * delta); ras.cover += delta; y1 += delta; ex1 += incr; @@ -618,7 +679,7 @@ } delta = y2 - y1; - ras.area += (TArea)( fx2 + ONE_PIXEL - first ) * delta; + ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); ras.cover += delta; } @@ -631,10 +692,10 @@ gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2; + TCoord ey1, ey2, fy1, fy2, mod; TPos dx, dy, x, x2; long p, first; - int delta, rem, mod, lift, incr; + int delta, rem, lift, incr; ey1 = TRUNC( ras.last_ey ); @@ -678,7 +739,7 @@ { TCoord ex = TRUNC( ras.x ); TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); - TPos area; + TArea area; first = ONE_PIXEL; @@ -693,7 +754,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( &ras, ex, ey1 ); + gray_set_cell( RAS_VAR_ ex, ey1 ); delta = (int)( first + first - ONE_PIXEL ); area = (TArea)two_fx * delta; @@ -703,7 +764,7 @@ ras.cover += delta; ey1 += incr; - gray_set_cell( &ras, ex, ey1 ); + gray_set_cell( RAS_VAR_ ex, ey1 ); } delta = (int)( fy2 - ONE_PIXEL + first ); @@ -1071,13 +1132,13 @@ /* record current cell, if any */ - gray_record_cell( worker ); + gray_record_cell( RAS_VAR ); /* start to a new position */ x = UPSCALE( to->x ); y = UPSCALE( to->y ); - gray_start_cell( worker, TRUNC( x ), TRUNC( y ) ); + gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); worker->x = x; worker->y = y; @@ -1089,7 +1150,7 @@ gray_line_to( const FT_Vector* to, PWorker worker ) { - gray_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) ); + gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); return 0; } @@ -1099,7 +1160,7 @@ const FT_Vector* to, PWorker worker ) { - gray_render_conic( worker, control, to ); + gray_render_conic( RAS_VAR_ control, to ); return 0; } @@ -1110,7 +1171,7 @@ const FT_Vector* to, PWorker worker ) { - gray_render_cubic( worker, control1, control2, to ); + gray_render_cubic( RAS_VAR_ control1, control2, to ); return 0; } @@ -1170,7 +1231,7 @@ gray_hline( RAS_ARG_ TCoord x, TCoord y, TPos area, - int acount ) + TCoord acount ) { FT_Span* span; int count; @@ -1207,9 +1268,13 @@ x += (TCoord)ras.min_ex; /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32768 ) + if ( x >= 32767 ) x = 32767; + /* FT_Span.y is an integer, so limit our coordinates appropriately */ + if ( y >= FT_INT_MAX ) + y = FT_INT_MAX; + if ( coverage ) { /* see whether we can add this span to the current list */ @@ -1229,27 +1294,26 @@ if ( ras.render_span && count > 0 ) ras.render_span( ras.span_y, count, ras.gray_spans, ras.render_span_data ); - /* ras.render_span( span->y, ras.gray_spans, count ); */ -#ifdef DEBUG_GRAYS +#ifdef FT_DEBUG_LEVEL_TRACE - if ( ras.span_y >= 0 ) + if ( count > 0 ) { int n; - fprintf( stderr, "y=%3d ", ras.span_y ); + FT_TRACE7(( "y = %3d ", ras.span_y )); span = ras.gray_spans; for ( n = 0; n < count; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); + FT_TRACE7(( "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage )); + FT_TRACE7(( "\n" )); } -#endif /* DEBUG_GRAYS */ +#endif /* FT_DEBUG_LEVEL_TRACE */ ras.num_gray_spans = 0; - ras.span_y = y; + ras.span_y = (int)y; count = 0; span = ras.gray_spans; @@ -1267,9 +1331,11 @@ } -#ifdef DEBUG_GRAYS +#ifdef FT_DEBUG_LEVEL_TRACE - /* to be called while in the debugger */ + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ + static void gray_dump_cells( RAS_ARG ) { int yindex; @@ -1283,12 +1349,12 @@ printf( "%3d:", yindex ); for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area ); + printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); printf( "\n" ); } } -#endif /* DEBUG_GRAYS */ +#endif /* FT_DEBUG_LEVEL_TRACE */ static void @@ -1304,6 +1370,8 @@ ras.num_gray_spans = 0; + FT_TRACE7(( "gray_sweep: start\n" )); + for ( yindex = 0; yindex < ras.ycount; yindex++ ) { PCell cell = ras.ycells[yindex]; @@ -1313,7 +1381,7 @@ for ( ; cell != NULL; cell = cell->next ) { - TArea area; + TPos area; if ( cell->x > x && cover != 0 ) @@ -1337,6 +1405,8 @@ if ( ras.render_span && ras.num_gray_spans > 0 ) ras.render_span( ras.span_y, ras.num_gray_spans, ras.gray_spans, ras.render_span_data ); + + FT_TRACE7(( "gray_sweep: end\n" )); } @@ -1344,7 +1414,7 @@ /*************************************************************************/ /* */ - /* The following function should only compile in stand_alone mode, */ + /* The following function should only compile in stand-alone mode, */ /* i.e., when building this component without the rest of FreeType. */ /* */ /*************************************************************************/ @@ -1355,18 +1425,19 @@ /* FT_Outline_Decompose */ /* */ /* <Description> */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and BĂ©zier arcs. This function is also able to emit */ /* `move to' and `close to' operations to indicate the start and end */ /* of new contours in the outline. */ /* */ /* <Input> */ /* outline :: A pointer to the source target. */ /* */ - /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* func_interface :: A table of `emitters', i.e., function pointers */ /* called during decomposition to indicate path */ /* operations. */ /* */ + /* <InOut> */ /* user :: A typeless pointer which is passed to each */ /* emitter during the decomposition. It can be */ /* used to store the state during the */ @@ -1375,17 +1446,13 @@ /* <Return> */ /* Error code. 0 means success. */ /* */ - static - int FT_Outline_Decompose( const FT_Outline* outline, - const FT_Outline_Funcs* func_interface, - void* user ) + static int + FT_Outline_Decompose( const FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) { #undef SCALED -#if 0 #define SCALED( x ) ( ( (x) << shift ) - delta ) -#else -#define SCALED( x ) (x) -#endif FT_Vector v_last; FT_Vector v_control; @@ -1395,17 +1462,21 @@ FT_Vector* limit; char* tags; + int error; + int n; /* index of contour in outline */ int first; /* index of first point in contour */ - int error; char tag; /* current point's state */ -#if 0 - int shift = func_interface->shift; - TPos delta = func_interface->delta; -#endif + int shift; + TPos delta; + if ( !outline || !func_interface ) + return ErrRaster_Invalid_Argument; + + shift = func_interface->shift; + delta = func_interface->delta; first = 0; for ( n = 0; n < outline->n_contours; n++ ) @@ -1413,22 +1484,25 @@ int last; /* index of last point in contour */ + FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); + last = outline->contours[n]; + if ( last < 0 ) + goto Invalid_Outline; limit = outline->points + last; - v_start = outline->points[first]; - v_last = outline->points[last]; - + v_start = outline->points[first]; v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); - v_last.y = SCALED( v_last.y ); + v_last = outline->points[last]; + v_last.x = SCALED( v_last.x ); + v_last.y = SCALED( v_last.y ); v_control = v_start; point = outline->points + first; - tags = outline->tags + first; + tags = outline->tags + first; tag = FT_CURVE_TAG( tags[0] ); /* A contour cannot start with a cubic control point! */ @@ -1459,6 +1533,8 @@ tags--; } + FT_TRACE5(( " move to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->move_to( &v_start, user ); if ( error ) goto Exit; @@ -1479,6 +1555,8 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " line to (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0 )); error = func_interface->line_to( &vec, user ); if ( error ) goto Exit; @@ -1486,53 +1564,60 @@ } case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) { - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); + FT_Vector vec; + FT_Vector v_middle; - Do_Conic: - if ( point < limit ) + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_CURVE_TAG_ON ) - { - error = func_interface->conic_to( &v_control, &vec, - user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = func_interface->conic_to( &v_control, &v_middle, - user ); + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &vec, user ); if ( error ) goto Exit; - - v_control = vec; - goto Do_Conic; + continue; } - error = func_interface->conic_to( &v_control, &v_start, - user ); - goto Close; + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_middle.x / 64.0, v_middle.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; } + FT_TRACE5(( " conic to (%.2f, %.2f)" + " with control (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + v_control.x / 64.0, v_control.y / 64.0 )); + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + default: /* FT_CURVE_TAG_CUBIC */ { FT_Vector vec1, vec2; @@ -1559,12 +1644,22 @@ vec.x = SCALED( point->x ); vec.y = SCALED( point->y ); + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + vec.x / 64.0, vec.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); if ( error ) goto Exit; continue; } + FT_TRACE5(( " cubic to (%.2f, %.2f)" + " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0, + vec1.x / 64.0, vec1.y / 64.0, + vec2.x / 64.0, vec2.y / 64.0 )); error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); goto Close; } @@ -1572,6 +1667,8 @@ } /* close the contour with a line segment */ + FT_TRACE5(( " line to (%.2f, %.2f)\n", + v_start.x / 64.0, v_start.y / 64.0 )); error = func_interface->line_to( &v_start, user ); Close: @@ -1581,9 +1678,11 @@ first = last + 1; } + FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); return 0; Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); return error; Invalid_Outline: @@ -1599,32 +1698,33 @@ } TBand; - - static int - gray_convert_glyph_inner( RAS_ARG ) - { - static - const FT_Outline_Funcs func_interface = - { + FT_DEFINE_OUTLINE_FUNCS(func_interface, (FT_Outline_MoveTo_Func) gray_move_to, (FT_Outline_LineTo_Func) gray_line_to, (FT_Outline_ConicTo_Func)gray_conic_to, (FT_Outline_CubicTo_Func)gray_cubic_to, 0, 0 - }; + ) + + static int + gray_convert_glyph_inner( RAS_ARG ) + { volatile int error = 0; +#ifdef FT_CONFIG_OPTION_PIC + FT_Outline_Funcs func_interface; + Init_Class_func_interface(&func_interface); +#endif + if ( ft_setjmp( ras.jump_buffer ) == 0 ) { error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); gray_record_cell( RAS_VAR ); } else - { error = ErrRaster_Memory_Overflow; - } return error; } @@ -1659,14 +1759,14 @@ ras.count_ex = ras.max_ex - ras.min_ex; ras.count_ey = ras.max_ey - ras.min_ey; - /* simple heuristic used to speed-up the bezier decomposition -- see */ + /* simple heuristic used to speed up the bezier decomposition -- see */ /* the code in gray_render_conic() and gray_render_cubic() for more */ /* details */ ras.conic_level = 32; ras.cubic_level = 16; { - int level = 0; + int level = 0; if ( ras.count_ex > 24 || ras.count_ey > 24 ) @@ -1678,10 +1778,12 @@ ras.cubic_level <<= level; } - /* setup vertical bands */ + /* set up vertical bands */ num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) num_bands = 1; - if ( num_bands >= 39 ) num_bands = 39; + if ( num_bands == 0 ) + num_bands = 1; + if ( num_bands >= 39 ) + num_bands = 39; ras.band_shoot = 0; @@ -1760,8 +1862,8 @@ /* be some problems. */ if ( middle == bottom ) { -#ifdef DEBUG_GRAYS - fprintf( stderr, "Rotten glyph!\n" ); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); #endif return 1; } @@ -1796,11 +1898,14 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( !outline ) + return ErrRaster_Invalid_Outline; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return 0; - if ( !outline || !outline->contours || !outline->points ) + if ( !outline->contours || !outline->points ) return ErrRaster_Invalid_Outline; if ( outline->n_points != @@ -1810,7 +1915,7 @@ worker = raster->worker; /* if direct mode is not set, we must have a target bitmap */ - if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 ) + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { if ( !target_map ) return ErrRaster_Invalid_Argument; @@ -1828,7 +1933,7 @@ return ErrRaster_Invalid_Mode; /* compute clipping box */ - if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 ) + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { /* compute clip box from target pixmap */ ras.clip_box.xMin = 0; @@ -1837,9 +1942,7 @@ ras.clip_box.yMax = target_map->rows; } else if ( params->flags & FT_RASTER_FLAG_CLIP ) - { ras.clip_box = params->clip_box; - } else { ras.clip_box.xMin = -32768L; @@ -1848,32 +1951,32 @@ ras.clip_box.yMax = 32767L; } - gray_init_cells( worker, raster->buffer, raster->buffer_size ); + gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size ); - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = raster->band_size; + ras.outline = *outline; + ras.num_cells = 0; + ras.invalid = 1; + ras.band_size = raster->band_size; ras.num_gray_spans = 0; - if ( target_map ) - ras.target = *target_map; - - ras.render_span = (FT_Raster_Span_Func)gray_render_span; - ras.render_span_data = &ras; - if ( params->flags & FT_RASTER_FLAG_DIRECT ) { ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; } + else + { + ras.target = *target_map; + ras.render_span = (FT_Raster_Span_Func)gray_render_span; + ras.render_span_data = &ras; + } - return gray_convert_glyph( worker ); + return gray_convert_glyph( RAS_VAR ); } - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ + /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ + /**** a static object. *****/ #ifdef _STANDALONE_ @@ -1968,8 +2071,7 @@ } - const FT_Raster_Funcs ft_grays_raster = - { + FT_DEFINE_RASTER_FUNCS(ft_grays_raster, FT_GLYPH_FORMAT_OUTLINE, (FT_Raster_New_Func) gray_raster_new, @@ -1977,7 +2079,12 @@ (FT_Raster_Set_Mode_Func)0, (FT_Raster_Render_Func) gray_raster_render, (FT_Raster_Done_Func) gray_raster_done - }; + ) /* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/lib/3rdparty/freetype/src/smooth/ftgrays.h b/lib/3rdparty/freetype/src/smooth/ftgrays.h index 2d409543dce..f20f55f14b6 100644 --- a/lib/3rdparty/freetype/src/smooth/ftgrays.h +++ b/lib/3rdparty/freetype/src/smooth/ftgrays.h @@ -28,6 +28,7 @@ #include "ftimage.h" #else #include <ft2build.h> +#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */ #include FT_IMAGE_H #endif diff --git a/lib/3rdparty/freetype/src/smooth/ftsmooth.c b/lib/3rdparty/freetype/src/smooth/ftsmooth.c index 85d04eb458e..eed63531572 100644 --- a/lib/3rdparty/freetype/src/smooth/ftsmooth.c +++ b/lib/3rdparty/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,10 +17,12 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H #include "ftsmooth.h" #include "ftgrays.h" +#include "ftspic.h" #include "ftsmerrs.h" @@ -153,7 +155,7 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - /* allocate new one, depends on pixel format */ + /* allocate new one */ pitch = width; if ( hmul ) { @@ -192,6 +194,19 @@ } } +#endif + +#if FT_UINT_MAX > 0xFFFFU + + /* Required check is ( pitch * height < FT_ULONG_MAX ), */ + /* but we care realistic cases only. Always pitch <= width. */ + if ( width > 0xFFFFU || height > 0xFFFFU ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n", + width, height )); + return Smooth_Err_Raster_Overflow; + } + #endif bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; @@ -294,13 +309,13 @@ for ( hh = height_org; hh > 0; hh-- ) { - memcpy( write, read, pitch ); + ft_memcpy( write, read, pitch ); write += pitch; - memcpy( write, read, pitch ); + ft_memcpy( write, read, pitch ); write += pitch; - memcpy( write, read, pitch ); + ft_memcpy( write, read, pitch ); write += pitch; read += pitch; } @@ -310,12 +325,19 @@ FT_Outline_Translate( outline, x_shift, y_shift ); + /* + * XXX: on 16bit system, we return an error for huge bitmap + * to prevent an overflow. + */ + if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) + return Smooth_Err_Invalid_Pixel_Size; + if ( error ) goto Exit; slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = x_left; - slot->bitmap_top = y_top; + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; Exit: if ( outline && origin ) @@ -376,10 +398,8 @@ } - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_smooth_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -392,7 +412,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -401,14 +421,12 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_lcd_renderer_class = - { - { + FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -421,7 +439,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -430,15 +448,11 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) + FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class, - - FT_CALLBACK_TABLE_DEF - const FT_Renderer_Class ft_smooth_lcdv_renderer_class = - { - { FT_MODULE_RENDERER, sizeof( FT_RendererRec ), @@ -451,7 +465,7 @@ (FT_Module_Constructor)ft_smooth_init, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 - }, + , FT_GLYPH_FORMAT_OUTLINE, @@ -460,8 +474,8 @@ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, (FT_Renderer_SetModeFunc) ft_smooth_set_mode, - (FT_Raster_Funcs*) &ft_grays_raster - }; + (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + ) /* END */ diff --git a/lib/3rdparty/freetype/src/smooth/ftsmooth.h b/lib/3rdparty/freetype/src/smooth/ftsmooth.h index 62cced44873..3708790df17 100644 --- a/lib/3rdparty/freetype/src/smooth/ftsmooth.h +++ b/lib/3rdparty/freetype/src/smooth/ftsmooth.h @@ -28,15 +28,15 @@ FT_BEGIN_HEADER #ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_std_renderer_class; + FT_DECLARE_RENDERER( ft_std_renderer_class ) #endif #ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_renderer_class ) - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_v_renderer_class; + FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) #endif diff --git a/lib/3rdparty/freetype/src/smooth/ftspic.c b/lib/3rdparty/freetype/src/smooth/ftspic.c new file mode 100644 index 00000000000..aa547fceb6d --- /dev/null +++ b/lib/3rdparty/freetype/src/smooth/ftspic.c @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* ftspic.c */ +/* */ +/* The FreeType position independent code services for smooth module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ftspic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ftgrays.c */ + void FT_Init_Class_ft_grays_raster(FT_Raster_Funcs*); + + void + ft_smooth_renderer_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->smooth ) + { + SmoothPIC* container = (SmoothPIC*)pic_container->smooth; + if(--container->ref_count) + return; + FT_FREE( container ); + pic_container->smooth = NULL; + } + } + + + FT_Error + ft_smooth_renderer_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + SmoothPIC* container; + FT_Memory memory = library->memory; + + /* since this function also serve smooth_lcd and smooth_lcdv renderers, + it implements reference counting */ + if(pic_container->smooth) + { + ((SmoothPIC*)pic_container->smooth)->ref_count++; + return error; + } + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->smooth = container; + container->ref_count = 1; + + /* initialize pointer table - this is how the module usually expects this data */ + FT_Init_Class_ft_grays_raster(&container->ft_grays_raster); +/*Exit:*/ + if(error) + ft_smooth_renderer_class_pic_free(library); + return error; + } + + /* re-route these init and free functions to the above functions */ + FT_Error ft_smooth_lcd_renderer_class_pic_init(FT_Library library) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcd_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + FT_Error ft_smooth_lcdv_renderer_class_pic_init(FT_Library library) + { + return ft_smooth_renderer_class_pic_init(library); + } + void ft_smooth_lcdv_renderer_class_pic_free(FT_Library library) + { + ft_smooth_renderer_class_pic_free(library); + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/base/_ftbase_ros.c b/lib/3rdparty/freetype/src/smooth/ftspic.h similarity index 55% rename from lib/3rdparty/freetype/src/base/_ftbase_ros.c rename to lib/3rdparty/freetype/src/smooth/ftspic.h index e1d32483287..c7e0ce9d892 100644 --- a/lib/3rdparty/freetype/src/base/_ftbase_ros.c +++ b/lib/3rdparty/freetype/src/smooth/ftspic.h @@ -1,11 +1,11 @@ /***************************************************************************/ /* */ -/* ftbase.c */ +/* ftspic.h */ /* */ -/* Single object library component (body only). */ +/* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -16,27 +16,35 @@ /***************************************************************************/ -#include <ft2build.h> +#ifndef __FTSPIC_H__ +#define __FTSPIC_H__ -#define FT_MAKE_OPTION_SINGLE_OBJECT + +FT_BEGIN_HEADER -#define FT_MulFix FT_MulFix_wrong -#include "ftcalc.c" -#undef FT_MulFix -#include "_ftmulfix_ros.c" +#include FT_INTERNAL_PIC_H -#include "ftdbgmem.c" -#include "ftgloadr.c" -#include "ftnames.c" -#include "ftobjs.c" -#include "ftoutln.c" -#include "ftrfork.c" -#include "ftstream.c" -#include "fttrigon.c" -#include "ftutil.c" +#ifndef FT_CONFIG_OPTION_PIC +#define FT_GRAYS_RASTER_GET ft_grays_raster + +#else /* FT_CONFIG_OPTION_PIC */ + + typedef struct SmoothPIC_ + { + int ref_count; + FT_Raster_Funcs ft_grays_raster; + } SmoothPIC; + +#define GET_PIC(lib) ((SmoothPIC*)((lib)->pic_container.smooth)) +#define FT_GRAYS_RASTER_GET (GET_PIC(library)->ft_grays_raster) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __FTSPIC_H__ */ -#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) -#include <ftmac.c> -#endif /* END */ diff --git a/lib/3rdparty/freetype/src/smooth/module.mk b/lib/3rdparty/freetype/src/smooth/module.mk index 05ad4ba0a89..47f6c040764 100644 --- a/lib/3rdparty/freetype/src/smooth/module.mk +++ b/lib/3rdparty/freetype/src/smooth/module.mk @@ -16,11 +16,11 @@ FTMODULE_H_COMMANDS += SMOOTH_RENDERER define SMOOTH_RENDERER -$(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) -$(OPEN_DRIVER)ft_smooth_lcd_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcd_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for LCDs$(ECHO_DRIVER_DONE) -$(OPEN_DRIVER)ft_smooth_lcdv_renderer_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcdv_renderer_class $(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for vertical LCDs$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/smooth/smooth.c b/lib/3rdparty/freetype/src/smooth/smooth.c index ff6be3e4007..a8ac51f9f8c 100644 --- a/lib/3rdparty/freetype/src/smooth/smooth.c +++ b/lib/3rdparty/freetype/src/smooth/smooth.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> +#include "ftspic.c" #include "ftgrays.c" #include "ftsmooth.c" diff --git a/lib/3rdparty/freetype/src/tools/apinames.c b/lib/3rdparty/freetype/src/tools/apinames.c index f08919bee6c..7f191e19c91 100644 --- a/lib/3rdparty/freetype/src/tools/apinames.c +++ b/lib/3rdparty/freetype/src/tools/apinames.c @@ -10,7 +10,7 @@ * accepted if you are using GCC for compilation (and probably by * other compilers too). * - * Author: David Turner, 2005, 2006 + * Author: David Turner, 2005, 2006, 2008, 2009 * * This code is explicitly placed into the public domain. * @@ -26,7 +26,7 @@ #define LINEBUFF_SIZE 1024 -typedef enum +typedef enum OutputFormat_ { OUTPUT_LIST = 0, /* output the list of names, one per line */ OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ @@ -44,7 +44,7 @@ panic( const char* message ) } -typedef struct +typedef struct NameRec_ { char* name; unsigned int hash; @@ -191,7 +191,7 @@ names_dump( FILE* out, /* states of the line parser */ -typedef enum +typedef enum State_ { STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */ STATE_TYPE /* type was read, waiting for function name */ @@ -265,7 +265,7 @@ read_header_file( FILE* file, int verbose ) if ( p > name ) { if ( verbose ) - fprintf( stderr, ">>> %.*s\n", p-name, name ); + fprintf( stderr, ">>> %.*s\n", (int)(p - name), name ); names_add( name, p ); } diff --git a/lib/3rdparty/freetype/src/tools/chktrcmp.py b/lib/3rdparty/freetype/src/tools/chktrcmp.py new file mode 100644 index 00000000000..d0f342e6bdd --- /dev/null +++ b/lib/3rdparty/freetype/src/tools/chktrcmp.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# +# Check trace components in FreeType 2 source. +# Author: suzuki toshiya, 2009 +# +# This code is explicitly into the public domain. + + +import sys +import os +import re + +SRC_FILE_LIST = [] +USED_COMPONENT = {} +KNOWN_COMPONENT = {} + +SRC_FILE_DIRS = [ "src" ] +TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ] + + +# -------------------------------------------------------------- +# Parse command line options +# + +for i in range( 1, len( sys.argv ) ): + if sys.argv[i].startswith( "--help" ): + print "Usage: %s [option]" % sys.argv[0] + print "Search used-but-defined and defined-but-not-used trace_XXX macros" + print "" + print " --help:" + print " Show this help" + print "" + print " --src-dirs=dir1:dir2:..." + print " Specify the directories of C source files to be checked" + print " Default is %s" % ":".join( SRC_FILE_DIRS ) + print "" + print " --def-files=file1:file2:..." + print " Specify the header files including FT_TRACE_DEF()" + print " Default is %s" % ":".join( TRACE_DEF_FILES ) + print "" + exit(0) + if sys.argv[i].startswith( "--src-dirs=" ): + SRC_FILE_DIRS = sys.argv[i].replace( "--src-dirs=", "", 1 ).split( ":" ) + elif sys.argv[i].startswith( "--def-files=" ): + TRACE_DEF_FILES = sys.argv[i].replace( "--def-files=", "", 1 ).split( ":" ) + + +# -------------------------------------------------------------- +# Scan C source and header files using trace macros. +# + +c_pathname_pat = re.compile( '^.*\.[ch]$', re.IGNORECASE ) +trace_use_pat = re.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' ) + +for d in SRC_FILE_DIRS: + for ( p, dlst, flst ) in os.walk( d ): + for f in flst: + if c_pathname_pat.match( f ) != None: + src_pathname = os.path.join( p, f ) + + line_num = 0 + for src_line in open( src_pathname, 'r' ): + line_num = line_num + 1 + src_line = src_line.strip() + if trace_use_pat.match( src_line ) != None: + component_name = trace_use_pat.sub( '', src_line ) + if component_name in USED_COMPONENT: + USED_COMPONENT[component_name].append( "%s:%d" % ( src_pathname, line_num ) ) + else: + USED_COMPONENT[component_name] = [ "%s:%d" % ( src_pathname, line_num ) ] + + +# -------------------------------------------------------------- +# Scan header file(s) defining trace macros. +# + +trace_def_pat_opn = re.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' ) +trace_def_pat_cls = re.compile( '[ \t\)].*$' ) + +for f in TRACE_DEF_FILES: + line_num = 0 + for hdr_line in open( f, 'r' ): + line_num = line_num + 1 + hdr_line = hdr_line.strip() + if trace_def_pat_opn.match( hdr_line ) != None: + component_name = trace_def_pat_opn.sub( '', hdr_line ) + component_name = trace_def_pat_cls.sub( '', component_name ) + if component_name in KNOWN_COMPONENT: + print "trace component %s is defined twice, see %s and fttrace.h:%d" % \ + ( component_name, KNOWN_COMPONENT[component_name], line_num ) + else: + KNOWN_COMPONENT[component_name] = "%s:%d" % \ + ( os.path.basename( f ), line_num ) + + +# -------------------------------------------------------------- +# Compare the used and defined trace macros. +# + +print "# Trace component used in the implementations but not defined in fttrace.h." +cmpnt = USED_COMPONENT.keys() +cmpnt.sort() +for c in cmpnt: + if c not in KNOWN_COMPONENT: + print "Trace component %s (used in %s) is not defined." % ( c, ", ".join( USED_COMPONENT[c] ) ) + +print "# Trace component is defined but not used in the implementations." +cmpnt = KNOWN_COMPONENT.keys() +cmpnt.sort() +for c in cmpnt: + if c not in USED_COMPONENT: + if c != "any": + print "Trace component %s (defined in %s) is not used." % ( c, KNOWN_COMPONENT[c] ) + diff --git a/lib/3rdparty/freetype/src/tools/docmaker/content.py b/lib/3rdparty/freetype/src/tools/docmaker/content.py index b14c52edefd..b398955b81d 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/content.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/content.py @@ -1,4 +1,5 @@ -# Content (c) 2002, 2004, 2006, 2007 David Turner <david@freetype.org> +# Content (c) 2002, 2004, 2006, 2007, 2008, 2009 +# David Turner <david@freetype.org> # # This file contains routines used to parse the content of documentation # comment blocks and build more structured objects out of them. @@ -34,6 +35,13 @@ re_code_end = re.compile( r"(\s*)}\s*$" ) re_identifier = re.compile( r'(\w*)' ) +# we collect macros ending in `_H'; while outputting the object data, we use +# this info together with the object's file location to emit the appropriate +# header file macro and name before the object itself +# +re_header_macro = re.compile( r'^#define\s{1,}(\w{1,}_H)\s{1,}<(.*)>' ) + + ############################################################################# # # The DocCode class is used to store source code lines. @@ -44,11 +52,11 @@ re_identifier = re.compile( r'(\w*)' ) # The object is filled line by line by the parser; it strips the leading # "margin" space from each input line before storing it in 'self.lines'. # -class DocCode: +class DocCode: - def __init__( self, margin, lines ): - self.lines = [] - self.words = None + def __init__( self, margin, lines ): + self.lines = [] + self.words = None # remove margin spaces for l in lines: @@ -56,15 +64,15 @@ class DocCode: l = l[margin:] self.lines.append( l ) - def dump( self, prefix = "", width=60 ): + def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: print prefix + l - def dump_lines( self, margin=0, width=60 ): + def dump_lines( self, margin = 0, width = 60 ): result = [] for l in self.lines: - result.append( " "*margin + l ) + result.append( " " * margin + l ) return result @@ -75,34 +83,34 @@ class DocCode: # # 'self.words' contains the list of words that make up the paragraph # -class DocPara: +class DocPara: - def __init__( self, lines ): + def __init__( self, lines ): self.lines = None self.words = [] for l in lines: - l = string.strip(l) + l = string.strip( l ) self.words.extend( string.split( l ) ) - def dump( self, prefix = "", width = 60 ): + def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: print prefix + l - def dump_lines( self, margin=0, width = 60 ): + def dump_lines( self, margin = 0, width = 60 ): cur = "" # current line col = 0 # current width result = [] for word in self.words: - ln = len(word) + ln = len( word ) if col > 0: - ln = ln+1 + ln = ln + 1 if col + ln > width: - result.append( " "*margin + cur ) + result.append( " " * margin + cur ) cur = word - col = len(word) + col = len( word ) else: if col > 0: cur = cur + " " @@ -110,31 +118,29 @@ class DocPara: col = col + ln if col > 0: - result.append( " "*margin + cur ) + result.append( " " * margin + cur ) return result - ############################################################################# # # The DocField class is used to store a list containing either DocPara or # DocCode objects. Each DocField also has an optional "name" which is used # when the object corresponds to a field or value definition # -class DocField: - - def __init__( self, name, lines ): +class DocField: + def __init__( self, name, lines ): self.name = name # can be None for normal paragraphs/sources - self.items = [] # list of items + self.items = [] # list of items - mode_none = 0 # start parsing mode - mode_code = 1 # parsing code sequences - mode_para = 3 # parsing normal paragraph + mode_none = 0 # start parsing mode + mode_code = 1 # parsing code sequences + mode_para = 3 # parsing normal paragraph - margin = -1 # current code sequence indentation + margin = -1 # current code sequence indentation cur_lines = [] # now analyze the markup lines to see if they contain paragraphs, @@ -142,14 +148,13 @@ class DocField: # start = 0 mode = mode_none - for l in lines: + for l in lines: # are we parsing a code sequence ? if mode == mode_code: - m = re_code_end.match( l ) - if m and len(m.group(1)) <= margin: - # that's it, we finised the code sequence + if m and len( m.group( 1 ) ) <= margin: + # that's it, we finished the code sequence code = DocCode( 0, cur_lines ) self.items.append( code ) margin = -1 @@ -169,9 +174,8 @@ class DocField: cur_lines = [] # switch to code extraction mode - margin = len(m.group(1)) + margin = len( m.group( 1 ) ) mode = mode_code - else: if not string.split( l ) and cur_lines: # if the line is empty, we end the current paragraph, @@ -188,12 +192,11 @@ class DocField: # unexpected end of code sequence code = DocCode( margin, cur_lines ) self.items.append( code ) - elif cur_lines: para = DocPara( cur_lines ) self.items.append( para ) - def dump( self, prefix = "" ): + def dump( self, prefix = "" ): if self.field: print prefix + self.field + " ::" prefix = prefix + "----" @@ -205,9 +208,10 @@ class DocField: p.dump( prefix ) first = 0 - def dump_lines( self, margin=0, width=60 ): + def dump_lines( self, margin = 0, width = 60 ): result = [] nl = None + for p in self.items: if nl: result.append( "" ) @@ -217,17 +221,19 @@ class DocField: return result + + # this regular expression is used to detect field definitions # -re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" ) +re_field = re.compile( r"\s*(\w*|\w(\w|\.)*\w)\s*::" ) -class DocMarkup: +class DocMarkup: - def __init__( self, tag, lines ): - self.tag = string.lower(tag) - self.fields = [] + def __init__( self, tag, lines ): + self.tag = string.lower( tag ) + self.fields = [] cur_lines = [] field = None @@ -245,10 +251,10 @@ class DocMarkup: cur_lines = [] field = None - field = m.group(1) # record field name - ln = len(m.group(0)) - l = " "*ln + l[ln:] - cur_lines = [ l ] + field = m.group( 1 ) # record field name + ln = len( m.group( 0 ) ) + l = " " * ln + l[ln:] + cur_lines = [l] else: cur_lines.append( l ) @@ -256,51 +262,48 @@ class DocMarkup: f = DocField( field, cur_lines ) self.fields.append( f ) - def get_name( self ): + def get_name( self ): try: return self.fields[0].items[0].words[0] - except: return None - def get_start( self ): + def get_start( self ): try: result = "" for word in self.fields[0].items[0].words: result = result + " " + word return result[1:] - except: return "ERROR" - def dump( self, margin ): - print " "*margin + "<" + self.tag + ">" + def dump( self, margin ): + print " " * margin + "<" + self.tag + ">" for f in self.fields: f.dump( " " ) - print " "*margin + "</" + self.tag + ">" + print " " * margin + "</" + self.tag + ">" +class DocChapter: -class DocChapter: - - def __init__( self, block ): + def __init__( self, block ): self.block = block self.sections = [] if block: - self.name = block.name - self.title = block.get_markup_words( "title" ) - self.order = block.get_markup_words( "sections" ) + self.name = block.name + self.title = block.get_markup_words( "title" ) + self.order = block.get_markup_words( "sections" ) else: - self.name = "Other" - self.title = string.split( "Miscellaneous" ) - self.order = [] + self.name = "Other" + self.title = string.split( "Miscellaneous" ) + self.order = [] -class DocSection: +class DocSection: - def __init__( self, name = "Other" ): + def __init__( self, name = "Other" ): self.name = name self.blocks = {} self.block_names = [] # ordered block names in section @@ -311,15 +314,15 @@ class DocSection: self.title = "ERROR" self.chapter = None - def add_def( self, block ): + def add_def( self, block ): self.defs.append( block ) - def add_block( self, block ): + def add_block( self, block ): self.block_names.append( block.name ) - self.blocks[ block.name ] = block + self.blocks[block.name] = block - def process( self ): - # lookup one block that contains a valid section description + def process( self ): + # look up one block that contains a valid section description for block in self.defs: title = block.get_markup_text( "title" ) if title: @@ -329,49 +332,51 @@ class DocSection: self.order = block.get_markup_words( "order" ) return - def reorder( self ): - + def reorder( self ): self.block_names = sort_order_list( self.block_names, self.order ) -class ContentProcessor: - def __init__( self ): +class ContentProcessor: + + def __init__( self ): """initialize a block content processor""" self.reset() self.sections = {} # dictionary of documentation sections self.section = None # current documentation section - self.chapters = [] # list of chapters + self.chapters = [] # list of chapters - def set_section( self, section_name ): + self.headers = {} # dictionary of header macros + + def set_section( self, section_name ): """set current section during parsing""" if not self.sections.has_key( section_name ): section = DocSection( section_name ) - self.sections[ section_name ] = section - self.section = section + self.sections[section_name] = section + self.section = section else: - self.section = self.sections[ section_name ] + self.section = self.sections[section_name] - def add_chapter( self, block ): + def add_chapter( self, block ): chapter = DocChapter( block ) self.chapters.append( chapter ) - def reset( self ): + def reset( self ): """reset the content processor for a new block""" self.markups = [] self.markup = None self.markup_lines = [] - def add_markup( self ): + def add_markup( self ): """add a new markup section""" if self.markup and self.markup_lines: # get rid of last line of markup if it's empty marks = self.markup_lines - if len(marks) > 0 and not string.strip(marks[-1]): + if len( marks ) > 0 and not string.strip( marks[-1] ): self.markup_lines = marks[:-1] m = DocMarkup( self.markup, self.markup_lines ) @@ -381,8 +386,7 @@ class ContentProcessor: self.markup = None self.markup_lines = [] - - def process_content( self, content ): + def process_content( self, content ): """process a block content and return a list of DocMarkup objects corresponding to it""" markup = None @@ -394,9 +398,9 @@ class ContentProcessor: for t in re_markup_tags: m = t.match( line ) if m: - found = string.lower(m.group(1)) - prefix = len(m.group(0)) - line = " "*prefix + line[prefix:] # remove markup from line + found = string.lower( m.group( 1 ) ) + prefix = len( m.group( 0 ) ) + line = " " * prefix + line[prefix:] # remove markup from line break # is it the start of a new markup section ? @@ -404,7 +408,7 @@ class ContentProcessor: first = 0 self.add_markup() # add current markup content self.markup = found - if len(string.strip( line )) > 0: + if len( string.strip( line ) ) > 0: self.markup_lines.append( line ) elif first == 0: self.markup_lines.append( line ) @@ -413,28 +417,25 @@ class ContentProcessor: return self.markups - def parse_sources( self, source_processor ): blocks = source_processor.blocks - count = len(blocks) - for n in range(count): + count = len( blocks ) + for n in range( count ): source = blocks[n] if source.content: # this is a documentation comment, we need to catch # all following normal blocks in the "follow" list # follow = [] - m = n+1 + m = n + 1 while m < count and not blocks[m].content: follow.append( blocks[m] ) - m = m+1 + m = m + 1 doc_block = DocBlock( source, follow, self ) - def finish( self ): - # process all sections to extract their abstract, description # and ordered list of items # @@ -445,13 +446,13 @@ class ContentProcessor: # listed there for chap in self.chapters: for sec in chap.order: - if self.sections.has_key(sec): - section = self.sections[ sec ] + if self.sections.has_key( sec ): + section = self.sections[sec] section.chapter = chap section.reorder() chap.sections.append( section ) else: - sys.stderr.write( "WARNING: chapter '" + + sys.stderr.write( "WARNING: chapter '" + \ chap.name + "' in " + chap.block.location() + \ " lists unknown section '" + sec + "'\n" ) @@ -460,7 +461,7 @@ class ContentProcessor: others = [] for sec in self.sections.values(): if not sec.chapter: - others.append(sec) + others.append( sec ) # create a new special chapter for all remaining sections # when necessary @@ -472,18 +473,17 @@ class ContentProcessor: -class DocBlock: - - def __init__( self, source, follow, processor ): +class DocBlock: + def __init__( self, source, follow, processor ): processor.reset() - self.source = source - self.code = [] - self.type = "ERRTYPE" - self.name = "ERRNAME" - self.section = processor.section - self.markups = processor.process_content( source.content ) + self.source = source + self.code = [] + self.type = "ERRTYPE" + self.name = "ERRNAME" + self.section = processor.section + self.markups = processor.process_content( source.content ) # compute block type from first markup tag try: @@ -491,7 +491,6 @@ class DocBlock: except: pass - # compute block name from first markup paragraph try: markup = self.markups[0] @@ -499,20 +498,18 @@ class DocBlock: name = para.words[0] m = re_identifier.match( name ) if m: - name = m.group(1) + name = m.group( 1 ) self.name = name except: pass - # detect new section starts if self.type == "section": + # detect new section starts processor.set_section( self.name ) processor.section.add_def( self ) - - # detect new chapter elif self.type == "chapter": + # detect new chapter processor.add_chapter( self ) - else: processor.section.add_block( self ) @@ -523,6 +520,11 @@ class DocBlock: if b.format: break for l in b.lines: + # collect header macro definitions + m = re_header_macro.match( l ) + if m: + processor.headers[m.group( 2 )] = m.group( 1 ); + # we use "/* */" as a separator if re_source_sep.match( l ): break @@ -530,7 +532,7 @@ class DocBlock: # now strip the leading and trailing empty lines from the sources start = 0 - end = len( source )-1 + end = len( source ) - 1 while start < end and not string.strip( source[start] ): start = start + 1 @@ -538,25 +540,22 @@ class DocBlock: while start < end and not string.strip( source[end] ): end = end - 1 - source = source[start:end+1] + if start == end and not string.strip( source[start] ): + self.code = [] + else: + self.code = source[start:end + 1] - self.code = source - - - def location( self ): + def location( self ): return self.source.location() - - - def get_markup( self, tag_name ): + def get_markup( self, tag_name ): """return the DocMarkup corresponding to a given tag in a block""" for m in self.markups: - if m.tag == string.lower(tag_name): + if m.tag == string.lower( tag_name ): return m return None - - def get_markup_name( self, tag_name ): + def get_markup_name( self, tag_name ): """return the name of a given primary markup in a block""" try: m = self.get_markup( tag_name ) @@ -564,21 +563,18 @@ class DocBlock: except: return None - - def get_markup_words( self, tag_name ): + def get_markup_words( self, tag_name ): try: m = self.get_markup( tag_name ) return m.fields[0].items[0].words except: return [] - - def get_markup_text( self, tag_name ): + def get_markup_text( self, tag_name ): result = self.get_markup_words( tag_name ) return string.join( result ) - - def get_markup_items( self, tag_name ): + def get_markup_items( self, tag_name ): try: m = self.get_markup( tag_name ) return m.fields[0].items diff --git a/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py b/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py index 55c43297f1f..3ddf4a94a15 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/docbeauty.py @@ -1,23 +1,24 @@ #!/usr/bin/env python # -# DocBeauty (c) 2003, 2004 David Turner <david@freetype.org> +# DocBeauty (c) 2003, 2004, 2008 David Turner <david@freetype.org> # # This program is used to beautify the documentation comments used # in the FreeType 2 public headers. # -from sources import * -from content import * -from utils import * +from sources import * +from content import * +from utils import * import utils import sys, os, time, string, getopt + content_processor = ContentProcessor() -def beautify_block( block ): +def beautify_block( block ): if block.content: content_processor.reset() @@ -30,7 +31,7 @@ def beautify_block( block ): first = 0 # now beautify the documentation "borders" themselves - lines = [ " /*************************************************************************" ] + lines = [" /*************************************************************************"] for l in text: lines.append( " *" + l ) lines.append( " */" ) @@ -38,9 +39,9 @@ def beautify_block( block ): block.lines = lines -def usage(): +def usage(): print "\nDocBeauty 0.1 Usage information\n" - print " docbeauty [options] file1 [ file2 ... ]\n" + print " docbeauty [options] file1 [file2 ...]\n" print "using the following options:\n" print " -h : print this page" print " -b : backup original files with the 'orig' extension" @@ -48,16 +49,15 @@ def usage(): print " --backup : same as -b" -def main( argv ): +def main( argv ): """main program loop""" global output_dir try: - opts, args = getopt.getopt( sys.argv[1:], - "hb", - [ "help", "backup" ] ) - + opts, args = getopt.getopt( sys.argv[1:], \ + "hb", \ + ["help", "backup"] ) except getopt.GetoptError: usage() sys.exit( 2 ) @@ -80,16 +80,19 @@ def main( argv ): do_backup = 1 # create context and processor - source_processor = SourceProcessor() + source_processor = SourceProcessor() # retrieve the list of files to process file_list = make_file_list( args ) for filename in file_list: source_processor.parse_file( filename ) + for block in source_processor.blocks: beautify_block( block ) + new_name = filename + ".new" ok = None + try: file = open( new_name, "wt" ) for block in source_processor.blocks: @@ -100,6 +103,7 @@ def main( argv ): except: ok = 0 + # if called from the command line # if __name__ == '__main__': diff --git a/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py b/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py index d34b6e8f96b..1d9de9fbff2 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/docmaker.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# DocMaker (c) 2002, 2004 David Turner <david@freetype.org> +# DocMaker (c) 2002, 2004, 2008 David Turner <david@freetype.org> # # This program is a re-write of the original DocMaker took used # to generate the API Reference of the FreeType font engine @@ -24,9 +24,9 @@ import utils import sys, os, time, string, glob, getopt -def usage(): +def usage(): print "\nDocMaker Usage information\n" - print " docmaker [options] file1 [ file2 ... ]\n" + print " docmaker [options] file1 [file2 ...]\n" print "using the following options:\n" print " -h : print this page" print " -t : set project title, as in '-t \"My Project\"'" @@ -38,16 +38,15 @@ def usage(): print " --prefix : same as -p, as in '--prefix=ft2'" -def main( argv ): +def main( argv ): """main program loop""" global output_dir try: - opts, args = getopt.getopt( sys.argv[1:], - "ht:o:p:", - [ "help", "title=", "output=", "prefix=" ] ) - + opts, args = getopt.getopt( sys.argv[1:], \ + "ht:o:p:", \ + ["help", "title=", "output=", "prefix="] ) except getopt.GetoptError: usage() sys.exit( 2 ) @@ -76,7 +75,7 @@ def main( argv ): if opt[0] in ( "-p", "--prefix" ): project_prefix = opt[1] - check_output( ) + check_output() # create context and processor source_processor = SourceProcessor() diff --git a/lib/3rdparty/freetype/src/tools/docmaker/formatter.py b/lib/3rdparty/freetype/src/tools/docmaker/formatter.py index 363410efc76..f62ce676c15 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/formatter.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/formatter.py @@ -1,4 +1,4 @@ -# Formatter (c) 2002, 2004, 2007 David Turner <david@freetype.org> +# Formatter (c) 2002, 2004, 2007, 2008 David Turner <david@freetype.org> # from sources import * @@ -14,10 +14,9 @@ from utils import * # used to output -- you guessed it -- HTML. # -class Formatter: - - def __init__( self, processor ): +class Formatter: + def __init__( self, processor ): self.processor = processor self.identifiers = {} self.chapters = processor.chapters @@ -25,7 +24,7 @@ class Formatter: self.block_index = [] # store all blocks in a dictionary - self.blocks = [] + self.blocks = [] for section in self.sections: for block in section.blocks.values(): self.add_identifier( block.name, block ) @@ -36,26 +35,22 @@ class Formatter: for field in markup.fields: self.add_identifier( field.name, block ) - self.block_index = self.identifiers.keys() self.block_index.sort( index_sort ) - - def add_identifier( self, name, block ): + def add_identifier( self, name, block ): if self.identifiers.has_key( name ): - # duplicate name !! - sys.stderr.write( \ + # duplicate name! + sys.stderr.write( \ "WARNING: duplicate definition for '" + name + "' in " + \ block.location() + ", previous definition in " + \ - self.identifiers[ name ].location() + "\n" ) + self.identifiers[name].location() + "\n" ) else: self.identifiers[name] = block - # # Formatting the table of contents # - def toc_enter( self ): pass @@ -78,7 +73,6 @@ class Formatter: pass def toc_dump( self, toc_filename = None, index_filename = None ): - output = None if toc_filename: output = open_output( toc_filename ) @@ -93,7 +87,7 @@ class Formatter: self.toc_section_enter( section ) self.toc_section_exit( section ) - self.toc_chapter_exit ( chap ) + self.toc_chapter_exit( chap ) self.toc_index( index_filename ) @@ -105,7 +99,6 @@ class Formatter: # # Formatting the index # - def index_enter( self ): pass @@ -119,7 +112,6 @@ class Formatter: pass def index_dump( self, index_filename = None ): - output = None if index_filename: output = open_output( index_filename ) @@ -128,7 +120,7 @@ class Formatter: for name in self.block_index: self.index_name_enter( name ) - self.index_name_exit ( name ) + self.index_name_exit( name ) self.index_exit() @@ -162,9 +154,7 @@ class Formatter: def section_exit( self, section ): pass - def section_dump( self, section, section_filename = None ): - output = None if section_filename: output = open_output( section_filename ) @@ -172,33 +162,27 @@ class Formatter: self.section_enter( section ) for name in section.block_names: - block = self.identifiers[ name ] + block = self.identifiers[name] self.block_enter( block ) - for markup in block.markups[1:]: # always ignore first markup !! + for markup in block.markups[1:]: # always ignore first markup! self.markup_enter( markup, block ) for field in markup.fields: self.field_enter( field, markup, block ) - - self.field_exit ( field, markup, block ) + self.field_exit( field, markup, block ) self.markup_exit( markup, block ) self.block_exit( block ) - self.section_exit ( section ) + self.section_exit( section ) if output: close_output( output ) - - def section_dump_all( self ): + def section_dump_all( self ): for section in self.sections: self.section_dump( section ) - # - # Formatting a block - # - # eof diff --git a/lib/3rdparty/freetype/src/tools/docmaker/sources.py b/lib/3rdparty/freetype/src/tools/docmaker/sources.py index 09ff7f9970d..7b68c07019d 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/sources.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/sources.py @@ -1,4 +1,4 @@ -# Sources (c) 2002, 2003, 2004, 2006, 2007 +# Sources (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009 # David Turner <david@freetype.org> # # @@ -18,13 +18,11 @@ # the classes and methods found here only deal with text parsing # and basic documentation block extraction # + import fileinput, re, sys, os, string - - - ################################################################ ## ## BLOCK FORMAT PATTERN @@ -36,11 +34,10 @@ import fileinput, re, sys, os, string ## note that the 'column' pattern must contain a group that will ## be used to "unbox" the content of documentation comment blocks ## -class SourceBlockFormat: +class SourceBlockFormat: - def __init__( self, id, start, column, end ): + def __init__( self, id, start, column, end ): """create a block pattern, used to recognize special documentation blocks""" - self.id = id self.start = re.compile( start, re.VERBOSE ) self.column = re.compile( column, re.VERBOSE ) @@ -61,9 +58,9 @@ class SourceBlockFormat: # start = r''' - \s* # any number of whitespace - /\*{2,}/ # followed by '/' and at least two asterisks then '/' - \s*$ # eventually followed by whitespace + \s* # any number of whitespace + /\*{2,}/ # followed by '/' and at least two asterisks then '/' + \s*$ # probably followed by whitespace ''' column = r''' @@ -71,11 +68,12 @@ column = r''' /\*{1} # followed by '/' and precisely one asterisk ([^*].*) # followed by anything (group 1) \*{1}/ # followed by one asterisk and a '/' - \s*$ # eventually followed by whitespace + \s*$ # probably followed by whitespace ''' re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) + # # format 2 documentation comment blocks look like the following: # @@ -91,27 +89,28 @@ re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) start = r''' \s* # any number of whitespace /\*{2,} # followed by '/' and at least two asterisks - \s*$ # eventually followed by whitespace + \s*$ # probably followed by whitespace ''' column = r''' - \s* # any number of whitespace - \*{1}(?!/) # followed by precisely one asterisk not followed by `/' - (.*) # then anything (group1) + \s* # any number of whitespace + \*{1}(?!/) # followed by precisely one asterisk not followed by `/' + (.*) # then anything (group1) ''' end = r''' - \s* # any number of whitespace - \*+/ # followed by at least one asterisk, then '/' + \s* # any number of whitespace + \*+/ # followed by at least one asterisk, then '/' ''' re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) + # # the list of supported documentation block formats, we could add new ones # relatively easily # -re_source_block_formats = [ re_source_block_format1, re_source_block_format2 ] +re_source_block_formats = [re_source_block_format1, re_source_block_format2] # @@ -128,7 +127,7 @@ re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format # the list of supported markup tags, we could add new ones relatively # easily # -re_markup_tags = [ re_markup_tag1, re_markup_tag2 ] +re_markup_tags = [re_markup_tag1, re_markup_tag2] # # used to detect a cross-reference, after markup tags have been stripped @@ -175,18 +174,19 @@ re_source_keywords = re.compile( '''\\b ( typedef | \#else | \#endif ) \\b''', re.VERBOSE ) + ################################################################ ## ## SOURCE BLOCK CLASS ## -## A SourceProcessor is in charge or reading a C source file +## A SourceProcessor is in charge of reading a C source file ## and decomposing it into a series of different "SourceBlocks". ## each one of these blocks can be made of the following data: ## ## - A documentation comment block that starts with "/**" and ## whose exact format will be discussed later ## -## - normal sources lines, include comments +## - normal sources lines, including comments ## ## the important fields in a text block are the following ones: ## @@ -198,8 +198,9 @@ re_source_keywords = re.compile( '''\\b ( typedef | ## (i.e. sources or ordinary comments with no starting ## markup tag) ## -class SourceBlock: - def __init__( self, processor, filename, lineno, lines ): +class SourceBlock: + + def __init__( self, processor, filename, lineno, lines ): self.processor = processor self.filename = filename self.lineno = lineno @@ -218,24 +219,22 @@ class SourceBlock: for line0 in self.lines: m = self.format.column.match( line0 ) if m: - lines.append( m.group(1) ) + lines.append( m.group( 1 ) ) # now, look for a markup tag for l in lines: - l = string.strip(l) - if len(l) > 0: + l = string.strip( l ) + if len( l ) > 0: for tag in re_markup_tags: if tag.match( l ): self.content = lines - return - - def location( self ): - return "(" + self.filename + ":" + repr(self.lineno) + ")" + return + def location( self ): + return "(" + self.filename + ":" + repr( self.lineno ) + ")" # debugging only - not used in normal operations - def dump( self ): - + def dump( self ): if self.content: print "{{{content start---" for l in self.content: @@ -245,17 +244,18 @@ class SourceBlock: fmt = "" if self.format: - fmt = repr(self.format.id) + " " + fmt = repr( self.format.id ) + " " for line in self.lines: print line + ################################################################ ## ## SOURCE PROCESSOR CLASS ## -## The SourceProcessor is in charge or reading a C source file +## The SourceProcessor is in charge of reading a C source file ## and decomposing it into a series of different "SourceBlock" ## objects. ## @@ -267,7 +267,7 @@ class SourceBlock: ## - normal sources lines, include comments ## ## -class SourceProcessor: +class SourceProcessor: def __init__( self ): """initialize a source processor""" @@ -281,39 +281,33 @@ class SourceProcessor: self.blocks = [] self.format = None - def parse_file( self, filename ): - """parse a C source file, and adds its blocks to the processor's list""" - + """parse a C source file, and add its blocks to the processor's list""" self.reset() self.filename = filename fileinput.close() - self.format = None - self.lineno = 0 - self.lines = [] + self.format = None + self.lineno = 0 + self.lines = [] for line in fileinput.input( filename ): - - # strip trailing newlines, important on Windows machines !! - if line[-1] == '\012': + # strip trailing newlines, important on Windows machines! + if line[-1] == '\012': line = line[0:-1] if self.format == None: self.process_normal_line( line ) - else: if self.format.end.match( line ): - # that's a normal block end, add it to lines and + # that's a normal block end, add it to 'lines' and # create a new block self.lines.append( line ) self.add_block_lines() - elif self.format.column.match( line ): # that's a normal column line, add it to 'lines' self.lines.append( line ) - else: # humm.. this is an unexpected block end, # create a new block, but don't process the line @@ -325,22 +319,18 @@ class SourceProcessor: # record the last lines self.add_block_lines() - - - def process_normal_line( self, line ): - """process a normal line and check if it's the start of a new block""" + def process_normal_line( self, line ): + """process a normal line and check whether it is the start of a new block""" for f in re_source_block_formats: - if f.start.match( line ): - self.add_block_lines() - self.format = f - self.lineno = fileinput.filelineno() + if f.start.match( line ): + self.add_block_lines() + self.format = f + self.lineno = fileinput.filelineno() self.lines.append( line ) - - - def add_block_lines( self ): - """add the current accumulated lines, and create a new block""" + def add_block_lines( self ): + """add the current accumulated lines and create a new block""" if self.lines != []: block = SourceBlock( self, self.filename, self.lineno, self.lines ) @@ -348,9 +338,8 @@ class SourceProcessor: self.format = None self.lines = [] - # debugging only, not used in normal operations - def dump( self ): + def dump( self ): """print all blocks in a processor""" for b in self.blocks: b.dump() diff --git a/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py b/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py index 04dfba3f46a..fffa120973d 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/tohtml.py @@ -1,4 +1,4 @@ -# ToHTML (c) 2002, 2003, 2005, 2006, 2007 +# ToHTML (c) 2002, 2003, 2005, 2006, 2007, 2008 # David Turner <david@freetype.org> from sources import * @@ -7,17 +7,19 @@ from formatter import * import time + # The following defines the HTML header used by all generated pages. -# html_header_1 = """\ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<title>""" +<title>\ +""" -html_header_2= """ API Reference +html_header_2 = """\ + API Reference -

""" +""" -html_header_3=""" API Reference

+html_header_3 = """ + + + +
[
[Index][TOC]
+

\ +""" + +html_header_5t = """\ +">Index] + +

\ +""" + +html_header_6 = """\ + API Reference

""" - # The HTML footer used by all generated pages. -# html_footer = """\ -""" +\ +""" # The header and footer used for each section. -# section_title_header = "

" section_title_footer = "

" # The header and footer used for code segments. -# code_header = '
'
 code_footer = '
' # Paragraph header and footer. -# para_header = "

" para_footer = "

" # Block header and footer. -# block_header = '
' block_footer_start = """\

- -
[
[Index] [TOC]
""" # Description header/footer. -# description_header = '
' description_footer = "

" # Marker header/inter/footer combination. -# marker_header = '
' marker_inter = "
" marker_footer = "
" +# Header location header/footer. +header_location_header = '
' +header_location_footer = "

" + # Source code extracts header/footer. -# source_header = '
\n'
 source_footer = "\n

" # Chapter header/inter/footer. -# chapter_header = '

' chapter_inter = '

  • ' chapter_footer = '
' @@ -114,86 +140,108 @@ chapter_footer = '' index_footer_start = """\
-
[TOC]
""" +# TOC footer. +toc_footer_start = """\ +
+ + +
[Index]
+""" + # source language keyword coloration/styling -# keyword_prefix = '' keyword_suffix = '' section_synopsis_header = '

Synopsis

' section_synopsis_footer = '' + # Translate a single line of source to HTML. This will convert # a "<" into "<.", ">" into ">.", etc. -# -def html_quote( line ): - result = string.replace( line, "&", "&" ) +def html_quote( line ): + result = string.replace( line, "&", "&" ) result = string.replace( result, "<", "<" ) result = string.replace( result, ">", ">" ) return result # same as 'html_quote', but ignores left and right brackets -# -def html_quote0( line ): +def html_quote0( line ): return string.replace( line, "&", "&" ) -def dump_html_code( lines, prefix = "" ): +def dump_html_code( lines, prefix = "" ): # clean the last empty lines - # l = len( self.lines ) while l > 0 and string.strip( self.lines[l - 1] ) == "": l = l - 1 # The code footer should be directly appended to the last code # line to avoid an additional blank line. - # print prefix + code_header, - for line in self.lines[0 : l+1]: - print '\n' + prefix + html_quote(line), + for line in self.lines[0 : l + 1]: + print '\n' + prefix + html_quote( line ), print prefix + code_footer, -class HtmlFormatter(Formatter): - - def __init__( self, processor, project_title, file_prefix ): +class HtmlFormatter( Formatter ): + def __init__( self, processor, project_title, file_prefix ): Formatter.__init__( self, processor ) - global html_header_1, html_header_2, html_header_3, html_footer + global html_header_1, html_header_2, html_header_3 + global html_header_4, html_header_5, html_footer if file_prefix: file_prefix = file_prefix + "-" else: file_prefix = "" - self.project_title = project_title - self.file_prefix = file_prefix - self.html_header = html_header_1 + project_title + html_header_2 + \ - project_title + html_header_3 + self.headers = processor.headers + self.project_title = project_title + self.file_prefix = file_prefix + self.html_header = html_header_1 + project_title + \ + html_header_2 + \ + html_header_3 + file_prefix + "index.html" + \ + html_header_4 + file_prefix + "toc.html" + \ + html_header_5 + project_title + \ + html_header_6 - self.html_footer = "
generated on " + \ - time.asctime( time.localtime( time.time() ) ) + \ - "
" + html_footer + self.html_index_header = html_header_1 + project_title + \ + html_header_2 + \ + html_header_3i + file_prefix + "toc.html" + \ + html_header_5 + project_title + \ + html_header_6 + + self.html_toc_header = html_header_1 + project_title + \ + html_header_2 + \ + html_header_3 + file_prefix + "index.html" + \ + html_header_5t + project_title + \ + html_header_6 + + self.html_footer = "
generated on " + \ + time.asctime( time.localtime( time.time() ) ) + \ + "
" + html_footer self.columns = 3 def make_section_url( self, section ): return self.file_prefix + section.name + ".html" - def make_block_url( self, block ): return self.make_section_url( block.section ) + "#" + block.name - def make_html_words( self, words ): """ convert a series of simple words into some HTML text """ line = "" @@ -204,16 +252,14 @@ class HtmlFormatter(Formatter): return line - def make_html_word( self, word ): """analyze a simple word to detect cross-references and styling""" # look for cross-references - # m = re_crossref.match( word ) if m: try: - name = m.group(1) - rest = m.group(2) + name = m.group( 1 ) + rest = m.group( 2 ) block = self.identifiers[name] url = self.make_block_url( block ) return '' + name + '' + rest @@ -226,34 +272,34 @@ class HtmlFormatter(Formatter): # look for italics and bolds m = re_italic.match( word ) if m: - name = m.group(1) - rest = m.group(3) + name = m.group( 1 ) + rest = m.group( 3 ) return '' + name + '' + rest m = re_bold.match( word ) if m: - name = m.group(1) - rest = m.group(3) + name = m.group( 1 ) + rest = m.group( 3 ) return '' + name + '' + rest - return html_quote(word) - + return html_quote( word ) def make_html_para( self, words ): - """ convert a paragraph's words into tagged HTML text, handle xrefs """ + """ convert words of a paragraph into tagged HTML text, handle xrefs """ line = "" if words: line = self.make_html_word( words[0] ) for word in words[1:]: line = line + " " + self.make_html_word( word ) # convert `...' quotations into real left and right single quotes - line = re.sub( r"(^|\W)`(.*?)'(\W|$)", - r'\1‘\2’\3', + line = re.sub( r"(^|\W)`(.*?)'(\W|$)", \ + r'\1‘\2’\3', \ line ) + # convert tilde into non-breakable space + line = string.replace( line, "~", " " ) return para_header + line + para_footer - def make_html_code( self, lines ): """ convert a code sequence to HTML """ line = code_header + '\n' @@ -262,7 +308,6 @@ class HtmlFormatter(Formatter): return line + code_footer - def make_html_items( self, items ): """ convert a field's content into some valid HTML """ lines = [] @@ -274,59 +319,54 @@ class HtmlFormatter(Formatter): return string.join( lines, '\n' ) - def print_html_items( self, items ): print self.make_html_items( items ) - - def print_html_field( self, field ): + def print_html_field( self, field ): if field.name: - print "

"+field.name+"

" + print "
" + field.name + "" print self.make_html_items( field.items ) if field.name: print "
" - - def html_source_quote( self, line, block_name = None ): + def html_source_quote( self, line, block_name = None ): result = "" while line: m = re_source_crossref.match( line ) if m: - name = m.group(2) - prefix = html_quote( m.group(1) ) - length = len( m.group(0) ) + name = m.group( 2 ) + prefix = html_quote( m.group( 1 ) ) + length = len( m.group( 0 ) ) if name == block_name: # this is the current block name, if any result = result + prefix + '' + name + '' - - elif re_source_keywords.match(name): + elif re_source_keywords.match( name ): # this is a C keyword result = result + prefix + keyword_prefix + name + keyword_suffix - - elif self.identifiers.has_key(name): + elif self.identifiers.has_key( name ): # this is a known identifier block = self.identifiers[name] result = result + prefix + '' + name + '' + self.make_block_url( block ) + '">' + name + '' else: - result = result + html_quote(line[:length]) + result = result + html_quote( line[:length] ) line = line[length:] else: - result = result + html_quote(line) + result = result + html_quote( line ) line = [] return result - - def print_html_field_list( self, fields ): + def print_html_field_list( self, fields ): + print "

" print "" for field in fields: - if len(field.name) > 22: - print "" + if len( field.name ) > 22: + print "" print "" print "
"+field.name+"
" + field.name + "
" else: print "
" + field.name + "" @@ -335,8 +375,7 @@ class HtmlFormatter(Formatter): print "
" - - def print_html_markup( self, markup ): + def print_html_markup( self, markup ): table_fields = [] for field in markup.fields: if field.name: @@ -345,7 +384,6 @@ class HtmlFormatter(Formatter): # all of them as a single table # table_fields.append( field ) - else: if table_fields: self.print_html_field_list( table_fields ) @@ -359,9 +397,8 @@ class HtmlFormatter(Formatter): # # Formatting the index # - def index_enter( self ): - print self.html_header + print self.html_index_header self.index_items = {} def index_name_enter( self, name ): @@ -370,16 +407,15 @@ class HtmlFormatter(Formatter): self.index_items[name] = url def index_exit( self ): - # block_index already contains the sorted list of index names count = len( self.block_index ) - rows = (count + self.columns - 1) / self.columns + rows = ( count + self.columns - 1 ) / self.columns print "" - for r in range(rows): + for r in range( rows ): line = "" - for c in range(self.columns): - i = r + c*rows + for c in range( self.columns ): + i = r + c * rows if i < count: bname = self.block_index[r + c * rows] url = self.index_items[bname] @@ -391,14 +427,15 @@ class HtmlFormatter(Formatter): print "
" - print index_footer_start + \ + print index_footer_start + \ self.file_prefix + "toc.html" + \ index_footer_end + print self.html_footer + self.index_items = {} def index_dump( self, index_filename = None ): - if index_filename == None: index_filename = self.file_prefix + "index.html" @@ -408,15 +445,15 @@ class HtmlFormatter(Formatter): # Formatting the table of content # def toc_enter( self ): - print self.html_header + print self.html_toc_header print "

Table of Contents

" def toc_chapter_enter( self, chapter ): - print chapter_header + string.join(chapter.title) + chapter_inter + print chapter_header + string.join( chapter.title ) + chapter_inter print "" def toc_section_enter( self, section ): - print "
" + print '
' print '' + \ section.title + '' @@ -427,12 +464,18 @@ class HtmlFormatter(Formatter): def toc_chapter_exit( self, chapter ): print "
" - print chapter_footer + print chapter_footer def toc_index( self, index_filename ): - print chapter_header + 'Global Index' + chapter_inter + chapter_footer + print chapter_header + \ + 'Global Index' + \ + chapter_inter + chapter_footer def toc_exit( self ): + print toc_footer_start + \ + self.file_prefix + "index.html" + \ + toc_footer_end + print self.html_footer def toc_dump( self, toc_filename = None, index_filename = None ): @@ -459,7 +502,7 @@ class HtmlFormatter(Formatter): if len( b.name ) > maxwidth: maxwidth = len( b.name ) - width = 70 # XXX magic number + width = 70 # XXX magic number if maxwidth <> 0: # print section synopsis print section_synopsis_header @@ -501,12 +544,26 @@ class HtmlFormatter(Formatter): # dump the block C source lines now if block.code: + header = '' + for f in self.headers.keys(): + if block.source.filename.find( f ) >= 0: + header = self.headers[f] + ' (' + f + ')' + break; + +# if not header: +# sys.stderr.write( \ +# 'WARNING: No header macro for ' + block.source.filename + '.\n' ) + + if header: + print header_location_header + print 'Defined in ' + header + '.' + print header_location_footer + print source_header for l in block.code: print self.html_source_quote( l, block.name ) print source_footer - def markup_enter( self, markup, block ): if markup.tag == "description": print description_header @@ -523,15 +580,13 @@ class HtmlFormatter(Formatter): def block_exit( self, block ): print block_footer_start + self.file_prefix + "index.html" + \ - block_footer_middle + self.file_prefix + "toc.html" + \ + block_footer_middle + self.file_prefix + "toc.html" + \ block_footer_end - def section_exit( self, section ): print html_footer - - def section_dump_all( self ): + def section_dump_all( self ): for section in self.sections: self.section_dump( section, self.file_prefix + section.name + '.html' ) diff --git a/lib/3rdparty/freetype/src/tools/docmaker/utils.py b/lib/3rdparty/freetype/src/tools/docmaker/utils.py index e751c563186..1d96658c7d5 100644 --- a/lib/3rdparty/freetype/src/tools/docmaker/utils.py +++ b/lib/3rdparty/freetype/src/tools/docmaker/utils.py @@ -1,4 +1,4 @@ -# Utils (c) 2002, 2004, 2007 David Turner +# Utils (c) 2002, 2004, 2007, 2008 David Turner # import string, sys, os, glob @@ -11,7 +11,7 @@ output_dir = None # This function is used to sort the index. It is a simple lexicographical # sort, except that it places capital letters before lowercase ones. # -def index_sort( s1, s2 ): +def index_sort( s1, s2 ): if not s1: return -1 @@ -41,9 +41,10 @@ def index_sort( s1, s2 ): return 0 + # Sort input_list, placing the elements of order_list in front. # -def sort_order_list( input_list, order_list ): +def sort_order_list( input_list, order_list ): new_list = order_list[:] for id in input_list: if not id in order_list: @@ -51,12 +52,11 @@ def sort_order_list( input_list, order_list ): return new_list - # Open the standard output to a given project documentation file. Use # "output_dir" to determine the filename location if necessary and save the # old stdout in a tuple that is returned by this function. # -def open_output( filename ): +def open_output( filename ): global output_dir if output_dir and output_dir != "": @@ -71,25 +71,26 @@ def open_output( filename ): # Close the output that was returned by "close_output". # -def close_output( output ): +def close_output( output ): output[0].close() sys.stdout = output[1] # Check output directory. # -def check_output( ): +def check_output(): global output_dir if output_dir: if output_dir != "": if not os.path.isdir( output_dir ): - sys.stderr.write( "argument" + " '" + output_dir + "' " + + sys.stderr.write( "argument" + " '" + output_dir + "' " + \ "is not a valid directory" ) sys.exit( 2 ) else: output_dir = None -def file_exists( pathname ): + +def file_exists( pathname ): """checks that a given file exists""" result = 1 try: @@ -102,9 +103,8 @@ def file_exists( pathname ): return result -def make_file_list( args = None ): +def make_file_list( args = None ): """builds a list of input files from command-line arguments""" - file_list = [] # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) diff --git a/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c b/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c index fcff27bc350..4daac0dc1d4 100644 --- a/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c +++ b/lib/3rdparty/freetype/src/tools/ftrandom/ftrandom.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 by George Williams */ +/* Copyright (C) 2005, 2007, 2008 by George Williams */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -151,8 +151,8 @@ int load_flags = FT_LOAD_DEFAULT; - if ( check_outlines && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + if ( check_outlines && + FT_IS_SCALABLE( face ) ) load_flags = FT_LOAD_NO_BITMAP; if ( nohints ) @@ -162,8 +162,8 @@ for ( gid = 0; gid < face->num_glyphs; ++gid ) { - if ( check_outlines && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + if ( check_outlines && + FT_IS_SCALABLE( face ) ) { if ( !FT_Load_Glyph( face, gid, load_flags ) ) FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL ); diff --git a/lib/3rdparty/freetype/src/tools/glnames.py b/lib/3rdparty/freetype/src/tools/glnames.py index 9a6da383172..55573b22fe8 100644 --- a/lib/3rdparty/freetype/src/tools/glnames.py +++ b/lib/3rdparty/freetype/src/tools/glnames.py @@ -6,7 +6,7 @@ # -# Copyright 1996-2000, 2003, 2005, 2007 by +# Copyright 1996-2000, 2003, 2005, 2007, 2008 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,7 +21,7 @@ usage: %s This python script generates the glyph names tables defined in the - PSNames module. + `psnames' module. Its single argument is the name of the header file to be created. """ @@ -5011,7 +5011,7 @@ def dump_array( the_array, write, array_name ): """dumps a given encoding""" write( " static const unsigned char " + array_name + - "[" + repr( len( the_array ) ) + "] =\n" ) + "[" + repr( len( the_array ) ) + "L] =\n" ) write( " {\n" ) line = "" @@ -5067,7 +5067,7 @@ def main(): write( "/* */\n" ) write( "/* PostScript glyph names. */\n" ) write( "/* */\n" ) - write( "/* Copyright 2005 by */\n" ) + write( "/* Copyright 2005, 2008 by */\n" ) write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) write( "/* */\n" ) write( "/* This file is part of the FreeType project, and may only be used, */\n" ) @@ -5117,6 +5117,9 @@ def main(): * The lookup function to get the Unicode value for a given string * is defined below the table. */ + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + """ ) dump_array( dict_array, write, "ft_adobe_glyph_list" ) @@ -5219,6 +5222,8 @@ def main(): return 0; } +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + """ ) if 0: # generate unit test, or don't diff --git a/lib/3rdparty/freetype/src/tools/test_afm.c b/lib/3rdparty/freetype/src/tools/test_afm.c index d53cb332562..f5f99363cab 100644 --- a/lib/3rdparty/freetype/src/tools/test_afm.c +++ b/lib/3rdparty/freetype/src/tools/test_afm.c @@ -63,7 +63,7 @@ int dummy_get_index( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ) { if ( len ) diff --git a/lib/3rdparty/freetype/src/truetype/Jamfile b/lib/3rdparty/freetype/src/truetype/Jamfile index a166909f4cc..a8cccfe1372 100644 --- a/lib/3rdparty/freetype/src/truetype/Jamfile +++ b/lib/3rdparty/freetype/src/truetype/Jamfile @@ -16,7 +16,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; if $(FT2_MULTI) { - _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ; + _sources = ttdriver ttobjs ttpload ttgload ttinterp ttgxvar ttpic ; } else { diff --git a/lib/3rdparty/freetype/src/truetype/module.mk b/lib/3rdparty/freetype/src/truetype/module.mk index 3b05afc7fda..baee81a7730 100644 --- a/lib/3rdparty/freetype/src/truetype/module.mk +++ b/lib/3rdparty/freetype/src/truetype/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TRUETYPE_DRIVER define TRUETYPE_DRIVER -$(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, tt_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/truetype/truetype.c b/lib/3rdparty/freetype/src/truetype/truetype.c index b36473a72df..4bd1209787e 100644 --- a/lib/3rdparty/freetype/src/truetype/truetype.c +++ b/lib/3rdparty/freetype/src/truetype/truetype.c @@ -19,6 +19,7 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include +#include "ttpic.c" #include "ttdriver.c" /* driver interface */ #include "ttpload.c" /* tables loader */ #include "ttgload.c" /* glyph loader */ diff --git a/lib/3rdparty/freetype/src/truetype/ttdriver.c b/lib/3rdparty/freetype/src/truetype/ttdriver.c index c2cf45298a5..d723b57ae9d 100644 --- a/lib/3rdparty/freetype/src/truetype/ttdriver.c +++ b/lib/3rdparty/freetype/src/truetype/ttdriver.c @@ -4,7 +4,8 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +21,6 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_SERVICE_XFREE86_NAME_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -41,6 +41,7 @@ #include "tterrors.h" +#include "ttpic.h" /*************************************************************************/ /* */ @@ -125,6 +126,49 @@ #undef PAIR_TAG + static FT_Error + tt_get_advances( FT_Face ttface, + FT_UInt start, + FT_UInt count, + FT_Int32 flags, + FT_Fixed *advances ) + { + FT_UInt nn; + TT_Face face = (TT_Face) ttface; + FT_Bool check = FT_BOOL( + !( flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) ); + + + /* XXX: TODO: check for sbits */ + + if ( flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short tsb; + FT_UShort ah; + + + TT_Get_VMetrics( face, start + nn, check, &tsb, &ah ); + advances[nn] = ah; + } + } + else + { + for ( nn = 0; nn < count; nn++ ) + { + FT_Short lsb; + FT_UShort aw; + + + TT_Get_HMetrics( face, start + nn, check, &lsb, &aw ); + advances[nn] = aw; + } + } + + return TT_Err_Ok; + } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -229,7 +273,7 @@ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ + /* FT_LOAD_XXX constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ @@ -255,14 +299,35 @@ if ( !size ) return TT_Err_Invalid_Size_Handle; - if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) + if ( !face ) return TT_Err_Invalid_Argument; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->num_glyphs && + !face->internal->incremental_interface ) +#else + if ( glyph_index >= (FT_UInt)face->num_glyphs ) +#endif + return TT_Err_Invalid_Argument; + + if ( load_flags & FT_LOAD_NO_HINTING ) + { + /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ + /* are necessary to disable hinting for tricky fonts */ + + if ( FT_IS_TRICKY( face ) ) + load_flags &= ~FT_LOAD_NO_HINTING; + + if ( load_flags & FT_LOAD_NO_AUTOHINT ) + load_flags |= FT_LOAD_NO_HINTING; + } + if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) { - load_flags |= FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP | - FT_LOAD_NO_SCALE; + load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; + + if ( !FT_IS_TRICKY( face ) ) + load_flags |= FT_LOAD_NO_HINTING; } /* now load the glyph outline if necessary */ @@ -288,14 +353,13 @@ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - static const FT_Service_MultiMastersRec tt_service_gx_multi_masters = - { + FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters, (FT_Get_MM_Func) NULL, (FT_Set_MM_Design_Func) NULL, (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, (FT_Get_MM_Var_Func) TT_Get_MM_Var, (FT_Set_Var_Design_Func)TT_Set_Var_Design - }; + ) #endif static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = @@ -315,22 +379,24 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; - static const FT_Service_TTGlyfRec tt_service_truetype_glyf = - { + FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf, (TT_Glyf_GetLocationFunc)tt_face_get_location - }; + ) - static const FT_ServiceDescRec tt_services[] = - { - { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters }, + FT_DEFINE_SERVICEDESCREC4(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) +#else + FT_DEFINE_SERVICEDESCREC3(tt_services, + FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET + ) #endif - { FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine }, - { FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf }, - { NULL, NULL } - }; - FT_CALLBACK_DEF( FT_Module_Interface ) tt_get_interface( FT_Module driver, /* TT_Driver */ @@ -340,11 +406,13 @@ FT_Module sfntd; SFNT_Service sfnt; - - result = ft_service_list_lookup( tt_services, tt_interface ); + result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface ); if ( result != NULL ) return result; + if ( !driver ) + return NULL; + /* only return the default interface from the SFNT module */ sfntd = FT_Get_Module( driver->library, "sfnt" ); if ( sfntd ) @@ -360,17 +428,24 @@ /* The FT_DriverInterface structure is defined in ftdriver.h. */ - FT_CALLBACK_TABLE_DEF - const FT_Driver_ClassRec tt_driver_class = - { - { +#ifdef TT_USE_BYTECODE_INTERPRETER +#define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER +#else +#define TT_HINTER_FLAG 0 +#endif + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#define TT_SIZE_SELECT tt_size_select +#else +#define TT_SIZE_SELECT 0 +#endif + + FT_DEFINE_DRIVER(tt_driver_class, + + FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | -#ifdef TT_USE_BYTECODE_INTERPRETER - FT_MODULE_DRIVER_HAS_HINTER, -#else - 0, -#endif + TT_HINTER_FLAG, sizeof ( TT_DriverRec ), @@ -383,7 +458,6 @@ tt_driver_init, tt_driver_done, tt_get_interface, - }, sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), @@ -396,23 +470,18 @@ tt_slot_init, 0, /* FT_Slot_DoneFunc */ -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - ft_stub_set_char_sizes, - ft_stub_set_pixel_sizes, -#endif + ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ + Load_Glyph, tt_get_kerning, 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + tt_get_advances, tt_size_request, -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - tt_size_select -#else - 0 /* FT_Size_SelectFunc */ -#endif - }; + TT_SIZE_SELECT + ) /* END */ diff --git a/lib/3rdparty/freetype/src/truetype/ttdriver.h b/lib/3rdparty/freetype/src/truetype/ttdriver.h index f6f26e4b59a..aae00f2617f 100644 --- a/lib/3rdparty/freetype/src/truetype/ttdriver.h +++ b/lib/3rdparty/freetype/src/truetype/ttdriver.h @@ -27,7 +27,7 @@ FT_BEGIN_HEADER - FT_EXPORT_VAR( const FT_Driver_ClassRec ) tt_driver_class; + FT_DECLARE_DRIVER( tt_driver_class ) FT_END_HEADER diff --git a/lib/3rdparty/freetype/src/truetype/ttgload.c b/lib/3rdparty/freetype/src/truetype/ttgload.c index ae476a41711..57ea0baa770 100644 --- a/lib/3rdparty/freetype/src/truetype/ttgload.c +++ b/lib/3rdparty/freetype/src/truetype/ttgload.c @@ -4,7 +4,8 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ +/* 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -69,17 +70,20 @@ /* `check' is true, take care of monospaced fonts by returning the */ /* advance width maximum. */ /* */ - static void - Get_HMetrics( TT_Face face, - FT_UInt idx, - FT_Bool check, - FT_Short* lsb, - FT_UShort* aw ) + FT_LOCAL_DEF( void ) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ) { ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw ); if ( check && face->postscript.isFixedPitch ) *aw = face->horizontal.advance_Width_Max; + + FT_TRACE5(( " advance width (font units): %d\n", *aw )); + FT_TRACE5(( " left side bearing (font units): %d\n", *lsb )); } @@ -96,12 +100,12 @@ /* The monospace `check' is probably not meaningful here, but we leave */ /* it in for a consistent interface. */ /* */ - static void - Get_VMetrics( TT_Face face, - FT_UInt idx, - FT_Bool check, - FT_Short* tsb, - FT_UShort* ah ) + FT_LOCAL_DEF( void ) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ) { FT_UNUSED( check ); @@ -131,6 +135,91 @@ #endif + FT_TRACE5(( " advance height (font units): %d\n", *ah )); + FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); + } + + + static void + tt_get_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + TT_Face face = (TT_Face)loader->face; + + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + + + TT_Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If this is an incrementally loaded font check whether there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + FT_Error error; + + + metrics.bearing_x = left_bearing; + metrics.bearing_y = 0; + metrics.advance = advance_width; + metrics.advance_v = 0; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + if ( error ) + goto Exit; + + left_bearing = (FT_Short)metrics.bearing_x; + advance_width = (FT_UShort)metrics.advance; + +#if 0 + + /* GWW: Do I do the same for vertical metrics? */ + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + +#endif /* 0 */ + + } + + Exit: + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } } @@ -267,7 +356,11 @@ if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) goto Invalid_Outline; - cont[0] = prev_cont = FT_NEXT_USHORT( p ); + prev_cont = FT_NEXT_USHORT( p ); + + if ( n_contours > 0 ) + cont[0] = prev_cont; + for ( cont++; cont < cont_limit; cont++ ) { cont[0] = FT_NEXT_USHORT( p ); @@ -313,7 +406,7 @@ if ( n_ins > face->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n", + FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", n_ins )); error = TT_Err_Too_Many_Hints; goto Fail; @@ -321,7 +414,7 @@ if ( ( limit - p ) < n_ins ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); + FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); error = TT_Err_Too_Many_Hints; goto Fail; } @@ -378,8 +471,8 @@ for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Pos y = 0; - FT_Byte f = *flag; + FT_Pos y = 0; + FT_Byte f = *flag; if ( f & 2 ) @@ -401,7 +494,8 @@ x += y; vec->x = x; - *flag = f & ~( 2 | 16 ); + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & ~( 2 | 16 ) ); } /* reading the Y coordinates */ @@ -413,8 +507,8 @@ for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Pos y = 0; - FT_Byte f = *flag; + FT_Pos y = 0; + FT_Byte f = *flag; if ( f & 4 ) @@ -436,7 +530,8 @@ x += y; vec->y = x; - *flag = f & FT_CURVE_TAG_ON; + /* the cast is for stupid compilers */ + *flag = (FT_Byte)( f & FT_CURVE_TAG_ON ); } outline->n_points = (FT_UShort)n_points; @@ -553,10 +648,10 @@ FT_Stream stream = loader->stream; - /* we must undo the FT_FRAME_ENTER in order to point to the */ - /* composite instructions, if we find some. */ - /* we will process them later... */ - /* */ + /* we must undo the FT_FRAME_ENTER in order to point */ + /* to the composite instructions, if we find some. */ + /* We will process them later. */ + /* */ loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + p - limit ); } @@ -627,7 +722,13 @@ #ifdef TT_USE_BYTECODE_INTERPRETER - n_ins = loader->glyph->control_len; + if ( loader->glyph->control_len > 0xFFFFL ) + { + FT_TRACE1(( "TT_Hint_Glyph: too long instructions " )); + FT_TRACE1(( "(0x%lx byte) is truncated\n", + loader->glyph->control_len )); + } + n_ins = (FT_UInt)( loader->glyph->control_len ); #endif origin = zone->cur[zone->n_points - 4].x; @@ -639,6 +740,26 @@ /* save original point position in org */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); + + /* Reset graphics state. */ + loader->exec->GS = ((TT_Size)loader->size)->GS; + + /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ + /* completely refer to the (already) hinted subglyphs. */ + if ( is_composite ) + { + loader->exec->metrics.x_scale = 1 << 16; + loader->exec->metrics.y_scale = 1 << 16; + + FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); + } + else + { + loader->exec->metrics.x_scale = + ((TT_Size)loader->size)->metrics.x_scale; + loader->exec->metrics.y_scale = + ((TT_Size)loader->size)->metrics.y_scale; + } #endif /* round pp2 and pp4 */ @@ -654,6 +775,9 @@ FT_Bool debug; FT_Error error; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline current_outline = gloader->current.outline; + error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph, loader->exec->glyphIns, n_ins ); @@ -669,6 +793,10 @@ error = TT_Run_Context( loader->exec, debug ); if ( error && loader->exec->pedantic_hinting ) return error; + + /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ + current_outline.tags[0] |= + ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; } #endif @@ -702,7 +830,7 @@ FT_GlyphLoader gloader = loader->gloader; FT_Error error = TT_Err_Ok; FT_Outline* outline; - FT_UInt n_points; + FT_Int n_points; outline = &gloader->current.outline; @@ -729,7 +857,7 @@ /* Deltas apply to the unscaled data. */ FT_Vector* deltas; FT_Memory memory = loader->face->memory; - FT_UInt i; + FT_Int i; error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face), @@ -903,15 +1031,15 @@ /* This algorithm is a guess and works much better than the above. */ /* */ FT_Fixed mac_xscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.xx, - subglyph->transform.xx ) + - FT_MulFix( subglyph->transform.xy, - subglyph->transform.xy ) ); + (FT_Int32)FT_MulFix( subglyph->transform.xx, + subglyph->transform.xx ) + + (FT_Int32)FT_MulFix( subglyph->transform.xy, + subglyph->transform.xy ) ); FT_Fixed mac_yscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.yy, - subglyph->transform.yy ) + - FT_MulFix( subglyph->transform.yx, - subglyph->transform.yx ) ); + (FT_Int32)FT_MulFix( subglyph->transform.yy, + subglyph->transform.yy ) + + (FT_Int32)FT_MulFix( subglyph->transform.yx, + subglyph->transform.yx ) ); x = FT_MulFix( x, mac_xscale ); @@ -1004,7 +1132,7 @@ /* check it */ if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n", + FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n", n_ins )); return TT_Err_Too_Many_Hints; @@ -1027,8 +1155,7 @@ /* Some points are likely touched during execution of */ /* instructions on components. So let's untouch them. */ for ( i = start_point; i < loader->zone.n_points; i++ ) - loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X | - FT_CURVE_TAG_TOUCH_Y ); + loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; loader->zone.n_points += 4; @@ -1064,9 +1191,10 @@ static FT_Error load_truetype_glyph( TT_Loader loader, FT_UInt glyph_index, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool header_only ) { - FT_Error error; + FT_Error error = TT_Err_Ok; FT_Fixed x_scale, y_scale; FT_ULong offset; TT_Face face = (TT_Face)loader->face; @@ -1084,7 +1212,10 @@ #endif - if ( recurse_count > face->max_profile.maxComponentDepth ) + /* some fonts have an incorrect value of `maxComponentDepth', */ + /* thus we allow depth 1 to catch the majority of them */ + if ( recurse_count > 1 && + recurse_count > face->max_profile.maxComponentDepth ) { error = TT_Err_Invalid_Composite; goto Exit; @@ -1110,75 +1241,7 @@ y_scale = 0x10000L; } - /* get metrics, horizontal and vertical */ - { - FT_Short left_bearing = 0, top_bearing = 0; - FT_UShort advance_width = 0, advance_height = 0; - - - Get_HMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &left_bearing, - &advance_width ); - Get_VMetrics( face, glyph_index, - (FT_Bool)!( loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), - &top_bearing, - &advance_height ); - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - /* If this is an incrementally loaded font see if there are */ - /* overriding metrics for this glyph. */ - if ( face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) - { - FT_Incremental_MetricsRec metrics; - - - metrics.bearing_x = left_bearing; - metrics.bearing_y = 0; - metrics.advance = advance_width; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - if ( error ) - goto Exit; - left_bearing = (FT_Short)metrics.bearing_x; - advance_width = (FT_UShort)metrics.advance; - -#if 0 - - /* GWW: Do I do the same for vertical metrics? */ - metrics.bearing_x = 0; - metrics.bearing_y = top_bearing; - metrics.advance = advance_height; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, TRUE, &metrics ); - if ( error ) - goto Exit; - top_bearing = (FT_Short)metrics.bearing_y; - advance_height = (FT_UShort)metrics.advance; - -#endif /* 0 */ - - } - -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - loader->top_bearing = top_bearing; - loader->vadvance = advance_height; - - if ( !loader->linear_def ) - { - loader->linear_def = 1; - loader->linear = advance_width; - } - } + tt_get_metrics( loader, glyph_index ); /* Set `offset' to the start of the glyph relative to the start of */ /* the `glyf' table, and `byte_len' to the length of the glyph in */ @@ -1214,15 +1277,45 @@ offset = tt_face_get_location( face, glyph_index, (FT_UInt*)&loader->byte_len ); - if ( loader->byte_len == 0 ) + if ( loader->byte_len > 0 ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* for the incremental interface, `glyf_offset' is always zero */ + if ( !loader->glyf_offset && + !face->root.internal->incremental_interface ) +#else + if ( !loader->glyf_offset ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); + error = TT_Err_Invalid_Table; + goto Exit; + } + + error = face->access_glyph_frame( loader, glyph_index, + loader->glyf_offset + offset, + loader->byte_len ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read glyph header first */ + error = face->read_glyph_header( loader ); + if ( error || header_only ) + goto Exit; + } + + if ( loader->byte_len == 0 || loader->n_contours == 0 ) { - /* as described by Frederic Loyer, these are spaces or */ - /* the unknown glyph. */ loader->bbox.xMin = 0; loader->bbox.xMax = 0; loader->bbox.yMin = 0; loader->bbox.yMax = 0; + if ( header_only ) + goto Exit; + TT_LOADER_SET_PP( loader ); #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT @@ -1260,19 +1353,6 @@ goto Exit; } - error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, - loader->byte_len ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read first glyph header */ - error = face->read_glyph_header( loader ); - if ( error ) - goto Exit; - TT_LOADER_SET_PP( loader ); /***********************************************************************/ @@ -1281,7 +1361,7 @@ /* if it is a simple glyph, load it */ - if ( loader->n_contours >= 0 ) + if ( loader->n_contours > 0 ) { error = face->read_simple_glyph( loader ); if ( error ) @@ -1351,8 +1431,11 @@ { if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 += deltas[i].x; - subglyph->arg2 += deltas[i].y; + /* XXX: overflow check for subglyph->{arg1,arg2}. */ + /* deltas[i].{x,y} must be within signed 16-bit, */ + /* but the restriction of summed delta is not clear */ + subglyph->arg1 += (FT_Int16)deltas[i].x; + subglyph->arg2 += (FT_Int16)deltas[i].y; } } @@ -1390,20 +1473,15 @@ /*********************************************************************/ { - FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; - FT_UInt num_points = start_point; - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; - FT_Stream old_stream = loader->stream; + FT_Stream old_stream = loader->stream; - TT_GraphicsState saved_GS; - - - if ( loader->exec ) - saved_GS = loader->exec->GS; FT_GlyphLoader_Add( gloader ); @@ -1413,10 +1491,6 @@ FT_Vector pp[4]; - /* reinitialize graphics state */ - if ( loader->exec ) - loader->exec->GS = saved_GS; - /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ @@ -1431,7 +1505,7 @@ num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, subglyph->index, - recurse_count + 1 ); + recurse_count + 1, FALSE ); if ( error ) goto Exit; @@ -1551,17 +1625,35 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* Now take care of vertical metrics. In the case where there is */ - /* no vertical information within the font (relatively common), make */ - /* up some metrics by `hand'... */ + /* adjust advance width to the value contained in the hdmx table */ + if ( !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) ) + { + FT_Byte* widthp; + + widthp = tt_face_get_device_metrics( face, + size->root.metrics.x_ppem, + glyph_index ); + + if ( widthp ) + glyph->metrics.horiAdvance = *widthp << 6; + } + + /* set glyph dimensions */ + glyph->metrics.width = bbox.xMax - bbox.xMin; + glyph->metrics.height = bbox.yMax - bbox.yMin; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), */ + /* create some metrics manually */ { FT_Pos top; /* scaled vertical top side bearing */ FT_Pos advance; /* scaled vertical advance height */ /* Get the unscaled top bearing and advance height. */ - if ( face->vertical_info && + if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax, @@ -1636,37 +1728,19 @@ /* scale the metrics */ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - top = FT_MulFix( top, y_scale ); + top = FT_MulFix( top, y_scale ); advance = FT_MulFix( advance, y_scale ); } /* XXX: for now, we have no better algorithm for the lsb, but it */ /* should work fine. */ /* */ - glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2; + glyph->metrics.vertBearingX = glyph->metrics.horiBearingX - + glyph->metrics.horiAdvance / 2; glyph->metrics.vertBearingY = top; glyph->metrics.vertAdvance = advance; } - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) ) - { - FT_Byte* widthp; - - - widthp = tt_face_get_device_metrics( face, - size->root.metrics.x_ppem, - glyph_index ); - - if ( widthp ) - glyph->metrics.horiAdvance = *widthp << 6; - } - - /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; - return 0; } @@ -1714,6 +1788,7 @@ glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; glyph->format = FT_GLYPH_FORMAT_BITMAP; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) { glyph->bitmap_left = metrics.vertBearingX; @@ -1736,7 +1811,8 @@ tt_loader_init( TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, - FT_Int32 load_flags ) + FT_Int32 load_flags, + FT_Bool glyf_table_only ) { TT_Face face; FT_Stream stream; @@ -1750,7 +1826,7 @@ #ifdef TT_USE_BYTECODE_INTERPRETER /* load execution context */ - if ( IS_HINTED( load_flags ) ) + if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; FT_Bool grayscale; @@ -1819,15 +1895,19 @@ FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); - if ( error ) + if ( error == TT_Err_Table_Missing ) + loader->glyf_offset = 0; + else if ( error ) { - FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); + FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); return error; } - loader->glyf_offset = FT_STREAM_POS(); + else + loader->glyf_offset = FT_STREAM_POS(); } /* get face's glyph loader */ + if ( !glyf_table_only ) { FT_GlyphLoader gloader = glyph->internal->loader; @@ -1836,7 +1916,7 @@ loader->gloader = gloader; } - loader->load_flags = load_flags; + loader->load_flags = load_flags; loader->face = (FT_Face)face; loader->size = (FT_Size)size; @@ -1899,7 +1979,25 @@ { error = load_sbit_image( size, glyph, glyph_index, load_flags ); if ( !error ) + { + FT_Face root = &face->root; + + + if ( FT_IS_SCALABLE( root ) ) + { + /* for the bbox we need the header only */ + (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); + (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + glyph->linearHoriAdvance = loader.linear; + glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - + loader.vadvance; + if ( face->postscript.isFixedPitch && + ( load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) + glyph->linearHoriAdvance = face->horizontal.advance_Width_Max; + } + return TT_Err_Ok; + } } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ @@ -1911,7 +2009,7 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) return TT_Err_Invalid_Argument; - error = tt_loader_init( &loader, size, glyph, load_flags ); + error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); if ( error ) return error; @@ -1920,7 +2018,7 @@ glyph->outline.flags = 0; /* main loading loop */ - error = load_truetype_glyph( &loader, glyph_index, 0 ); + error = load_truetype_glyph( &loader, glyph_index, 0, FALSE ); if ( !error ) { if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE ) @@ -1939,6 +2037,40 @@ FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 ); } +#ifdef TT_USE_BYTECODE_INTERPRETER + + if ( IS_HINTED( load_flags ) ) + { + if ( loader.exec->GS.scan_control ) + { + /* convert scan conversion mode to FT_OUTLINE_XXX flags */ + switch ( loader.exec->GS.scan_type ) + { + case 0: /* simple drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS; + break; + case 1: /* simple drop-outs excluding stubs */ + /* nothing; it's the default rendering mode */ + break; + case 4: /* smart drop-outs including stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS | + FT_OUTLINE_INCLUDE_STUBS; + break; + case 5: /* smart drop-outs excluding stubs */ + glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS; + break; + + default: /* no drop-out control */ + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + break; + } + } + else + glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS; + } + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + compute_glyph_metrics( &loader, glyph_index ); } diff --git a/lib/3rdparty/freetype/src/truetype/ttgload.h b/lib/3rdparty/freetype/src/truetype/ttgload.h index b261e97dee0..958d67d20d7 100644 --- a/lib/3rdparty/freetype/src/truetype/ttgload.h +++ b/lib/3rdparty/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,6 +34,20 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Init_Glyph_Loading( TT_Face face ); + FT_LOCAL( void ) + TT_Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ); + + FT_LOCAL( void ) + TT_Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ); + FT_LOCAL( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, diff --git a/lib/3rdparty/freetype/src/truetype/ttgxvar.c b/lib/3rdparty/freetype/src/truetype/ttgxvar.c index 0dc2c4f3e4a..ef25aafb5bf 100644 --- a/lib/3rdparty/freetype/src/truetype/ttgxvar.c +++ b/lib/3rdparty/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004, 2005, 2006, 2007 by */ +/* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,30 +16,31 @@ /***************************************************************************/ -/***************************************************************************/ -/* */ -/* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ -/* */ -/* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ -/* */ -/* The documentation for `fvar' is inconsistent. At one point it says */ -/* that `countSizePairs' should be 3, at another point 2. It should be 2. */ -/* */ -/* The documentation for `gvar' is not intelligible; `cvar' refers you to */ -/* `gvar' and is thus also incomprehensible. */ -/* */ -/* The documentation for `avar' appears correct, but Apple has no fonts */ -/* with an `avar' table, so it is hard to test. */ -/* */ -/* Many thanks to John Jenkins (at Apple) in figuring this out. */ -/* */ -/* */ -/* Apple's `kern' table has some references to tuple indices, but as there */ -/* is no indication where these indices are defined, nor how to */ -/* interpolate the kerning values (different tuples have different */ -/* classes) this issue is ignored. */ -/* */ -/***************************************************************************/ + /*************************************************************************/ + /* */ + /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at */ + /* */ + /* http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html */ + /* */ + /* The documentation for `fvar' is inconsistent. At one point it says */ + /* that `countSizePairs' should be 3, at another point 2. It should */ + /* be 2. */ + /* */ + /* The documentation for `gvar' is not intelligible; `cvar' refers you */ + /* to `gvar' and is thus also incomprehensible. */ + /* */ + /* The documentation for `avar' appears correct, but Apple has no fonts */ + /* with an `avar' table, so it is hard to test. */ + /* */ + /* Many thanks to John Jenkins (at Apple) in figuring this out. */ + /* */ + /* */ + /* Apple's `kern' table has some references to tuple indices, but as */ + /* there is no indication where these indices are defined, nor how to */ + /* interpolate the kerning values (different tuples have different */ + /* classes) this issue is ignored. */ + /* */ + /*************************************************************************/ #include @@ -47,11 +48,9 @@ #include FT_CONFIG_CONFIG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_MULTIPLE_MASTERS_H -#include "ttdriver.h" #include "ttpload.h" #include "ttgxvar.h" @@ -95,11 +94,8 @@ #define ALL_POINTS (FT_UShort*)( -1 ) - enum - { - GX_PT_POINTS_ARE_WORDS = 0x80, - GX_PT_POINT_RUN_COUNT_MASK = 0x7F - }; +#define GX_PT_POINTS_ARE_WORDS 0x80 +#define GX_PT_POINT_RUN_COUNT_MASK 0x7F /*************************************************************************/ @@ -158,6 +154,9 @@ runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK; first = points[i++] = FT_GET_USHORT(); + if ( runcnt < 1 ) + goto Exit; + /* first point not included in runcount */ for ( j = 0; j < runcnt; ++j ) points[i++] = (FT_UShort)( first += FT_GET_USHORT() ); @@ -166,11 +165,15 @@ { first = points[i++] = FT_GET_BYTE(); + if ( runcnt < 1 ) + goto Exit; + for ( j = 0; j < runcnt; ++j ) points[i++] = (FT_UShort)( first += FT_GET_BYTE() ); } } + Exit: return points; } @@ -205,12 +208,12 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, - FT_Int delta_cnt ) + FT_Offset delta_cnt ) { FT_Short *deltas; - FT_Int runcnt; - FT_Int i; - FT_Int j; + FT_UInt runcnt; + FT_Offset i; + FT_UInt j; FT_Memory memory = stream->memory; FT_Error error = TT_Err_Ok; @@ -337,7 +340,8 @@ } - typedef struct GX_GVar_Head_ { + typedef struct GX_GVar_Head_ + { FT_Long version; FT_UShort axisCount; FT_UShort globalCoordCount; @@ -564,7 +568,8 @@ /*************************************************************************/ - typedef struct GX_FVar_Head_ { + typedef struct GX_FVar_Head_ + { FT_Long version; FT_UShort offsetToData; FT_UShort countSizePairs; @@ -576,7 +581,8 @@ } GX_FVar_Head; - typedef struct fvar_axis { + typedef struct fvar_axis_ + { FT_ULong axisTag; FT_ULong minValue; FT_ULong defaultValue; @@ -754,7 +760,7 @@ } ns = mmvar->namedstyle; - for ( i = 0; i < fvar_head.instanceCount; ++i ) + for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns ) { if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) goto Exit; @@ -902,13 +908,15 @@ } else { - for ( i = 0; - i < num_coords && blend->normalizedcoords[i] == coords[i]; - ++i ); - if ( i == num_coords ) - manageCvt = mcvt_retain; - else + manageCvt = mcvt_retain; + for ( i = 0; i < num_coords; ++i ) + { + if ( blend->normalizedcoords[i] != coords[i] ) + { manageCvt = mcvt_load; + break; + } + } /* If we don't change the blend coords then we don't need to do */ /* anything to the cvt table. It will be correct. Otherwise we */ @@ -1127,7 +1135,7 @@ if ( blend == NULL ) { - FT_TRACE2(( "no blend specified!\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); error = TT_Err_Ok; goto Exit; @@ -1135,7 +1143,7 @@ if ( face->cvt == NULL ) { - FT_TRACE2(( "no `cvt ' table!\n" )); + FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); error = TT_Err_Ok; goto Exit; @@ -1144,7 +1152,7 @@ error = face->goto_table( face, TTAG_cvar, stream, &table_len ); if ( error ) { - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); error = TT_Err_Ok; goto Exit; @@ -1159,7 +1167,7 @@ table_start = FT_Stream_FTell( stream ); if ( FT_GET_LONG() != 0x00010000L ) { - FT_TRACE2(( "bad table version!\n" )); + FT_TRACE2(( "bad table version\n" )); error = TT_Err_Ok; goto FExit; diff --git a/lib/3rdparty/freetype/src/truetype/ttgxvar.h b/lib/3rdparty/freetype/src/truetype/ttgxvar.h index 706cb4d369b..82dfc4431f2 100644 --- a/lib/3rdparty/freetype/src/truetype/ttgxvar.h +++ b/lib/3rdparty/freetype/src/truetype/ttgxvar.h @@ -84,7 +84,7 @@ FT_BEGIN_HEADER FT_Fixed* normalizedcoords; FT_MM_Var* mmvar; - FT_Int mmvar_len; + FT_Offset mmvar_len; FT_Bool avar_checked; GX_AVarSegment avar_segment; diff --git a/lib/3rdparty/freetype/src/truetype/ttinterp.c b/lib/3rdparty/freetype/src/truetype/ttinterp.c index 85c8529ac73..13aa9a27c4c 100644 --- a/lib/3rdparty/freetype/src/truetype/ttinterp.c +++ b/lib/3rdparty/freetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -693,7 +693,7 @@ /* exec :: A handle to the target execution context. */ /* */ /* */ - /* TrueTyoe error code. 0 means success. */ + /* TrueType error code. 0 means success. */ /* */ /* */ /* Only the glyph loader and debugger should call this function. */ @@ -748,6 +748,13 @@ } + /* The default value for `scan_control' is documented as FALSE in the */ + /* TrueType specification. This is confusing since it implies a */ + /* Boolean value. However, this is not the case, thus both the */ + /* default values of our `scan_type' and `scan_control' fields (which */ + /* the documentation's `scan_control' variable is split into) are */ + /* zero. */ + const TT_GraphicsState tt_default_graphics_state = { 0, 0, 0, @@ -761,7 +768,7 @@ 1, 64, 1, TRUE, 68, 0, 0, 9, 3, - 0, FALSE, 2, 1, 1, 1 + 0, FALSE, 0, 1, 1, 1 }; @@ -784,9 +791,9 @@ /* allocate object */ if ( FT_NEW( exec ) ) - goto Exit; + goto Fail; - /* initialize it */ + /* initialize it; in case of error this deallocates `exec' too */ error = Init_Context( exec, memory ); if ( error ) goto Fail; @@ -795,13 +802,10 @@ driver->context = exec; } - Exit: return driver->context; Fail: - FT_FREE( exec ); - - return 0; + return NULL; } @@ -2190,7 +2194,7 @@ FT_ASSERT( !CUR.face->unpatented_hinting ); #endif - return TT_DotFix14( dx, dy, + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, CUR.GS.projVector.x, CUR.GS.projVector.y ); } @@ -2216,7 +2220,7 @@ Dual_Project( EXEC_OP_ FT_Pos dx, FT_Pos dy ) { - return TT_DotFix14( dx, dy, + return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy, CUR.GS.dualVector.x, CUR.GS.dualVector.y ); } @@ -4286,13 +4290,21 @@ CUR.numFDefs++; } + /* Although FDEF takes unsigned 32-bit integer, */ + /* func # must be within unsigned 16-bit integer */ + if ( n > 0xFFFFU ) + { + CUR.error = TT_Err_Too_Many_Function_Defs; + return; + } + rec->range = CUR.curRange; - rec->opc = n; + rec->opc = (FT_UInt16)n; rec->start = CUR.IP + 1; rec->active = TRUE; if ( n > CUR.maxFunc ) - CUR.maxFunc = n; + CUR.maxFunc = (FT_UInt16)n; /* Now skip the whole function definition. */ /* We don't allow nested IDEFS & FDEFs. */ @@ -4549,13 +4561,20 @@ CUR.numIDefs++; } - def->opc = args[0]; + /* opcode must be unsigned 8-bit integer */ + if ( 0 > args[0] || args[0] > 0x00FF ) + { + CUR.error = TT_Err_Too_Many_Instruction_Defs; + return; + } + + def->opc = (FT_Byte)args[0]; def->start = CUR.IP+1; def->range = CUR.curRange; def->active = TRUE; if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = args[0]; + CUR.maxIns = (FT_Byte)args[0]; /* Now skip the whole function definition. */ /* We don't allow nested IDEFs & FDEFs. */ @@ -4821,7 +4840,28 @@ if ( CUR.opcode & 1 ) D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); else - D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); + { + FT_Vector* vec1 = CUR.zp0.orus + L; + FT_Vector* vec2 = CUR.zp1.orus + K; + + + if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) + { + /* this should be faster */ + D = CUR_Func_dualproj( vec1, vec2 ); + D = TT_MULFIX( D, CUR.metrics.x_scale ); + } + else + { + FT_Vector vec; + + + vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); + vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); + + D = CUR_fast_dualproj( &vec ); + } + } } args[0] = D; @@ -5071,12 +5111,8 @@ return; } - A *= 64; - -#if 0 - if ( ( args[0] & 0x100 ) != 0 && CUR.metrics.pointSize <= A ) + if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A ) CUR.GS.scan_control = TRUE; -#endif if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated ) CUR.GS.scan_control = TRUE; @@ -5084,10 +5120,8 @@ if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched ) CUR.GS.scan_control = TRUE; -#if 0 - if ( ( args[0] & 0x800 ) != 0 && CUR.metrics.pointSize > A ) + if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A ) CUR.GS.scan_control = FALSE; -#endif if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated ) CUR.GS.scan_control = FALSE; @@ -5106,16 +5140,8 @@ static void Ins_SCANTYPE( INS_ARG ) { - /* for compatibility with future enhancements, */ - /* we must ignore new modes */ - - if ( args[0] >= 0 && args[0] <= 5 ) - { - if ( args[0] == 3 ) - args[0] = 2; - + if ( args[0] >= 0 ) CUR.GS.scan_type = (FT_Int)args[0]; - } } @@ -5428,7 +5454,7 @@ /* XXX: this is probably wrong... at least it prevents memory */ /* corruption when zp2 is the twilight zone */ - if ( last_point > CUR.zp2.n_points ) + if ( BOUNDS( last_point, CUR.zp2.n_points ) ) { if ( CUR.zp2.n_points > 0 ) last_point = (FT_UShort)(CUR.zp2.n_points - 1); @@ -5516,20 +5542,20 @@ { if ( CUR.GS.both_x_axis ) { - dx = TT_MulFix14( args[0], 0x4000 ); + dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); dy = 0; } else { dx = 0; - dy = TT_MulFix14( args[0], 0x4000 ); + dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); } } else #endif { - dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); + dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); } while ( CUR.GS.loop > 0 ) @@ -5695,8 +5721,8 @@ if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ { - CUR.zp0.org[point].x = TT_MulFix14( distance, CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( distance, CUR.GS.freeVector.y ), + CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.x ); + CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.y ), CUR.zp0.cur[point] = CUR.zp0.org[point]; } @@ -5883,10 +5909,12 @@ if ( CUR.GS.gep1 == 0 ) { CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MulFix14( cvt_dist, CUR.GS.freeVector.x ); + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.x ); CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MulFix14( cvt_dist, CUR.GS.freeVector.y ); + TT_MulFix14( (FT_UInt32)cvt_dist, + CUR.GS.freeVector.y ); CUR.zp1.cur[point] = CUR.zp0.cur[point]; } @@ -6211,9 +6239,13 @@ org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); - new_dist = ( old_range != 0 ) - ? TT_MULDIV( org_dist, cur_range, old_range ) - : cur_dist; + + if ( org_dist ) + new_dist = ( old_range != 0 ) + ? TT_MULDIV( org_dist, cur_range, old_range ) + : cur_dist; + else + new_dist = 0; CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); } @@ -6257,7 +6289,7 @@ /* Local variables for Ins_IUP: */ - typedef struct + typedef struct IUP_WorkerRec_ { FT_Vector* orgs; /* original and current coordinate */ FT_Vector* curs; /* arrays */ @@ -6370,7 +6402,7 @@ { scale_valid = 1; scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ), - 0x10000, orus2 - orus1 ); + 0x10000L, orus2 - orus1 ); } x = ( org1 + delta1 ) + @@ -6434,6 +6466,9 @@ end_point = CUR.pts.contours[contour] - CUR.pts.first_point; first_point = point; + if ( CUR.pts.n_points <= end_point ) + end_point = CUR.pts.n_points; + while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) point++; diff --git a/lib/3rdparty/freetype/src/truetype/ttobjs.c b/lib/3rdparty/freetype/src/truetype/ttobjs.c index 0294a1b7e66..11d662d2d49 100644 --- a/lib/3rdparty/freetype/src/truetype/ttobjs.c +++ b/lib/3rdparty/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,9 +18,7 @@ #include #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H @@ -144,6 +142,40 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ + /* Compare the face with a list of well-known `tricky' fonts. */ + /* This list shall be expanded as we find more of them. */ + + static FT_Bool + tt_check_trickyness( FT_String* name ) + { +#define TRICK_NAMES_MAX_CHARACTERS 16 +#define TRICK_NAMES_COUNT 7 + static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] = + { + "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiShu", + "DFKai-SB", /* kaiu.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "MingLiU", /* mingliu.ttf & mingliu.ttc */ + "PMingLiU", /* mingliu.ttc */ + "MingLi43", /* mingli.ttf */ + }; + int nn; + + + if ( !name ) + return FALSE; + + /* Note that we only check the face name at the moment; it might */ + /* be worth to do more checks for a few special cases. */ + for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) + if ( ft_strstr( name, trick_names[nn] ) ) + return TRUE; + + return FALSE; + } + + /*************************************************************************/ /* */ /* */ @@ -180,7 +212,7 @@ TT_Face face = (TT_Face)ttface; - library = face->root.driver->root.library; + library = ttface->driver->root.library; sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); if ( !sfnt ) goto Bad_Format; @@ -206,7 +238,7 @@ } #ifdef TT_USE_BYTECODE_INTERPRETER - face->root.face_flags |= FT_FACE_FLAG_HINTER; + ttface->face_flags |= FT_FACE_FLAG_HINTER; #endif /* If we are performing a simple font format check, exit immediately. */ @@ -218,29 +250,37 @@ if ( error ) goto Exit; + if ( tt_check_trickyness( ttface->family_name ) ) + ttface->face_flags |= FT_FACE_FLAG_TRICKY; + error = tt_face_load_hdmx( face, stream ); if ( error ) goto Exit; - if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) + if ( FT_IS_SCALABLE( ttface ) ) { #ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( !face->root.internal->incremental_interface ) + if ( !ttface->internal->incremental_interface ) error = tt_face_load_loca( face, stream ); if ( !error ) - error = tt_face_load_cvt( face, stream ) || - tt_face_load_fpgm( face, stream ) || - tt_face_load_prep( face, stream ); + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); #else if ( !error ) - error = tt_face_load_loca( face, stream ) || - tt_face_load_cvt( face, stream ) || - tt_face_load_fpgm( face, stream ) || - tt_face_load_prep( face, stream ); + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ); + if ( !error ) + error = tt_face_load_fpgm( face, stream ); + if ( !error ) + error = tt_face_load_prep( face, stream ); #endif @@ -262,38 +302,8 @@ if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) unpatented_hinting = TRUE; - /* Compare the face with a list of well-known `tricky' fonts. */ - /* This list shall be expanded as we find more of them. */ if ( !unpatented_hinting ) - { - static const char* const trick_names[] = - { - "DFKaiSho-SB", /* dfkaisb.ttf */ - "DFKai-SB", /* kaiu.ttf */ - "HuaTianSongTi?", /* htst3.ttf */ - "MingLiU", /* mingliu.ttf & mingliu.ttc */ - "PMingLiU", /* mingliu.ttc */ - "MingLi43", /* mingli.ttf */ - NULL - }; - int nn; - - - /* Note that we only check the face name at the moment; it might */ - /* be worth to do more checks for a few special cases. */ - for ( nn = 0; trick_names[nn] != NULL; nn++ ) - { - if ( ttface->family_name && - ft_strstr( ttface->family_name, trick_names[nn] ) ) - { - unpatented_hinting = 1; - break; - } - } - } - - ttface->internal->ignore_unpatented_hinter = - FT_BOOL( !unpatented_hinting ); + ttface->internal->ignore_unpatented_hinter = TRUE; } #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && @@ -325,12 +335,18 @@ FT_LOCAL_DEF( void ) tt_face_done( FT_Face ttface ) /* TT_Face */ { - TT_Face face = (TT_Face)ttface; - FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; + TT_Face face = (TT_Face)ttface; + FT_Memory memory; + FT_Stream stream; + SFNT_Service sfnt; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + if ( !face ) + return; + + memory = ttface->memory; + stream = ttface->stream; + sfnt = (SFNT_Service)face->sfnt; /* for `extended TrueType formats' (i.e. compressed versions) */ if ( face->extra.finalizer ) @@ -595,18 +611,15 @@ /* Set default metrics */ { - FT_Size_Metrics* metrics = &size->metrics; - TT_Size_Metrics* metrics2 = &size->ttmetrics; + TT_Size_Metrics* metrics = &size->ttmetrics; - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics2->rotated = FALSE; - metrics2->stretched = FALSE; + metrics->rotated = FALSE; + metrics->stretched = FALSE; /* set default compensation (all 0) */ for ( i = 0; i < 4; i++ ) - metrics2->compensations[i] = 0; + metrics->compensations[i] = 0; } /* allocate function defs, instruction defs, cvt, and storage area */ @@ -669,7 +682,7 @@ if ( !size->cvt_ready ) { FT_UInt i; - TT_Face face = (TT_Face) size->root.face; + TT_Face face = (TT_Face)size->root.face; /* Scale the cvt values to the new ppem. */ @@ -694,8 +707,9 @@ error = tt_size_run_prep( size ); if ( !error ) - size->cvt_ready = 1; + size->cvt_ready = 1; } + Exit: return error; } diff --git a/lib/3rdparty/freetype/src/truetype/ttobjs.h b/lib/3rdparty/freetype/src/truetype/ttobjs.h index 6971013af90..30c8669cb2d 100644 --- a/lib/3rdparty/freetype/src/truetype/ttobjs.h +++ b/lib/3rdparty/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -99,6 +99,10 @@ FT_BEGIN_HEADER FT_Short delta_shift; FT_Byte instruct_control; + /* According to Greg Hitchcock from Microsoft, the `scan_control' */ + /* variable as documented in the TrueType specification is a 32-bit */ + /* integer; the high-word part holds the SCANTYPE value, the low-word */ + /* part the SCANCTRL value. We separate it into two fields. */ FT_Bool scan_control; FT_Int scan_type; @@ -190,45 +194,13 @@ FT_BEGIN_HEADER } TT_Transform; - /*************************************************************************/ - /* */ - /* Subglyph loading record. Used to load composite components. */ - /* */ - typedef struct TT_SubglyphRec_ - { - FT_Long index; /* subglyph index; initialized with -1 */ - FT_Bool is_scaled; /* is the subglyph scaled? */ - FT_Bool is_hinted; /* should it be hinted? */ - FT_Bool preserve_pps; /* preserve phantom points? */ - - FT_Long file_offset; - - FT_BBox bbox; - FT_Pos left_bearing; - FT_Pos advance; - - TT_GlyphZoneRec zone; - - FT_Long arg1; /* first argument */ - FT_Long arg2; /* second argument */ - - FT_UShort element_flag; /* current load element flag */ - - TT_Transform transform; /* transformation matrix */ - - FT_Vector pp1, pp2; /* phantom points (horizontal) */ - FT_Vector pp3, pp4; /* phantom points (vertical) */ - - } TT_SubGlyphRec, *TT_SubGlyph_Stack; - - /*************************************************************************/ /* */ /* A note regarding non-squared pixels: */ /* */ /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here to explain some definitions in the TIns_Metrics */ - /* record). */ + /* is kept here to explain some definitions in the TT_Size_Metrics */ + /* record). */ /* */ /* The CVT is a one-dimensional array containing values that control */ /* certain important characteristics in a font, like the height of all */ diff --git a/lib/3rdparty/freetype/src/truetype/ttpic.c b/lib/3rdparty/freetype/src/truetype/ttpic.c new file mode 100644 index 00000000000..27ec4a1d5e5 --- /dev/null +++ b/lib/3rdparty/freetype/src/truetype/ttpic.c @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* ttpic.c */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "ttpic.h" + +#ifdef FT_CONFIG_OPTION_PIC + + /* forward declaration of PIC init functions from ttdriver.c */ + FT_Error FT_Create_Class_tt_services( FT_Library, FT_ServiceDescRec**); + void FT_Destroy_Class_tt_services( FT_Library, FT_ServiceDescRec*); + void FT_Init_Class_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*); + void FT_Init_Class_tt_service_truetype_glyf(FT_Service_TTGlyfRec*); + + void + tt_driver_class_pic_free( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Memory memory = library->memory; + if ( pic_container->truetype ) + { + TTModulePIC* container = (TTModulePIC*)pic_container->truetype; + if(container->tt_services) + FT_Destroy_Class_tt_services(library, container->tt_services); + container->tt_services = NULL; + FT_FREE( container ); + pic_container->truetype = NULL; + } + } + + FT_Error + tt_driver_class_pic_init( FT_Library library ) + { + FT_PIC_Container* pic_container = &library->pic_container; + FT_Error error = FT_Err_Ok; + TTModulePIC* container; + FT_Memory memory = library->memory; + + /* allocate pointer, clear and set global container pointer */ + if ( FT_ALLOC ( container, sizeof ( *container ) ) ) + return error; + FT_MEM_SET( container, 0, sizeof(*container) ); + pic_container->truetype = container; + + /* initialize pointer table - this is how the module usually expects this data */ + error = FT_Create_Class_tt_services(library, &container->tt_services); + if(error) + goto Exit; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Init_Class_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters); +#endif + FT_Init_Class_tt_service_truetype_glyf(&container->tt_service_truetype_glyf); +Exit: + if(error) + tt_driver_class_pic_free(library); + return error; + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/truetype/ttpic.h b/lib/3rdparty/freetype/src/truetype/ttpic.h new file mode 100644 index 00000000000..84de0fee9e3 --- /dev/null +++ b/lib/3rdparty/freetype/src/truetype/ttpic.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttpic.h */ +/* */ +/* The FreeType position independent code services for truetype module. */ +/* */ +/* Copyright 2009 by */ +/* Oran Agra and Mickey Gabel. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTPIC_H__ +#define __TTPIC_H__ + + +FT_BEGIN_HEADER + +#ifndef FT_CONFIG_OPTION_PIC +#define FT_TT_SERVICES_GET tt_services +#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define FT_TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf + +#else /* FT_CONFIG_OPTION_PIC */ + +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_TRUETYPE_GLYF_H + + typedef struct TTModulePIC_ + { + FT_ServiceDescRec* tt_services; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MultiMastersRec tt_service_gx_multi_masters; +#endif + FT_Service_TTGlyfRec tt_service_truetype_glyf; + } TTModulePIC; + +#define GET_PIC(lib) ((TTModulePIC*)((lib)->pic_container.truetype)) +#define FT_TT_SERVICES_GET (GET_PIC(library)->tt_services) +#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET (GET_PIC(library)->tt_service_gx_multi_masters) +#define FT_TT_SERVICE_TRUETYPE_GLYF_GET (GET_PIC(library)->tt_service_truetype_glyf) + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + +FT_END_HEADER + +#endif /* __TTPIC_H__ */ + + +/* END */ diff --git a/lib/3rdparty/freetype/src/truetype/ttpload.c b/lib/3rdparty/freetype/src/truetype/ttpload.c index 9d3381bf056..a311b03c00c 100644 --- a/lib/3rdparty/freetype/src/truetype/ttpload.c +++ b/lib/3rdparty/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,18 +58,23 @@ /* */ /* FreeType error code. 0 means success. */ /* */ - FT_LOCAL_DEF( FT_Error ) tt_face_load_loca( TT_Face face, FT_Stream stream ) { FT_Error error; FT_ULong table_len; + FT_Int shift; /* we need the size of the `glyf' table for malformed `loca' tables */ error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len ); - if ( error ) + + /* it is possible that a font doesn't have a glyf table at all */ + /* or its size is zero */ + if ( error == TT_Err_Table_Missing ) + face->glyf_len = 0; + else if ( error ) goto Exit; FT_TRACE2(( "Locations " )); @@ -82,23 +87,65 @@ if ( face->header.Index_To_Loc_Format != 0 ) { + shift = 2; + if ( table_len >= 0x40000L ) { - FT_TRACE2(( "table too large!\n" )); + FT_TRACE2(( "table too large\n" )); error = TT_Err_Invalid_Table; goto Exit; } - face->num_locations = (FT_UInt)( table_len >> 2 ); + face->num_locations = table_len >> shift; } else { + shift = 1; + if ( table_len >= 0x20000L ) { - FT_TRACE2(( "table too large!\n" )); + FT_TRACE2(( "table too large\n" )); error = TT_Err_Invalid_Table; goto Exit; } - face->num_locations = (FT_UInt)( table_len >> 1 ); + face->num_locations = table_len >> shift; + } + + if ( face->num_locations != (FT_ULong)face->root.num_glyphs ) + { + FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", + face->num_locations, face->root.num_glyphs )); + + /* we only handle the case where `maxp' gives a larger value */ + if ( face->num_locations < (FT_ULong)face->root.num_glyphs ) + { + FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift; + + TT_Table entry = face->dir_tables; + TT_Table limit = entry + face->num_tables; + + FT_Long pos = FT_Stream_Pos( stream ); + FT_Long dist = 0x7FFFFFFFL; + + + /* compute the distance to next table in font file */ + for ( ; entry < limit; entry++ ) + { + FT_Long diff = entry->Offset - pos; + + + if ( diff > 0 && diff < dist ) + dist = diff; + } + + if ( new_loca_len <= dist ) + { + face->num_locations = face->root.num_glyphs; + table_len = new_loca_len; + + FT_TRACE2(( "adjusting num_locations to %d\n", + face->num_locations )); + } + } } /* @@ -156,12 +203,14 @@ } } - /* It isn't mentioned explicitly that the `loca' table must be */ - /* ordered, but implicitly it refers to the length of an entry */ - /* as the difference between the current and the next position. */ - /* Anyway, there do exist (malformed) fonts which don't obey */ - /* this rule, so we are only able to provide an upper bound for */ - /* the size. */ + /* The `loca' table must be ordered; it refers to the length of */ + /* an entry as the difference between the current and the next */ + /* position. However, there do exist (malformed) fonts which */ + /* don't obey this rule, so we are only able to provide an */ + /* upper bound for the size. */ + /* */ + /* We get (intentionally) a wrong, non-zero result in case the */ + /* `glyf' table is missing. */ if ( pos2 >= pos1 ) *asize = (FT_UInt)( pos2 - pos1 ); else @@ -216,7 +265,7 @@ error = face->goto_table( face, TTAG_cvt, stream, &table_len ); if ( error ) { - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); face->cvt_size = 0; face->cvt = NULL; @@ -301,7 +350,7 @@ face->font_program_size = 0; error = TT_Err_Ok; - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); } else { @@ -362,7 +411,7 @@ face->cvt_program_size = 0; error = TT_Err_Ok; - FT_TRACE2(( "is missing!\n" )); + FT_TRACE2(( "is missing\n" )); } else { diff --git a/lib/3rdparty/freetype/src/type1/module.mk b/lib/3rdparty/freetype/src/type1/module.mk index baf98c00ea5..ade0210d76c 100644 --- a/lib/3rdparty/freetype/src/type1/module.mk +++ b/lib/3rdparty/freetype/src/type1/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TYPE1_DRIVER define TYPE1_DRIVER -$(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, t1_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/type1/t1afm.c b/lib/3rdparty/freetype/src/type1/t1afm.c index b81a8df83ab..ef343901a44 100644 --- a/lib/3rdparty/freetype/src/type1/t1afm.c +++ b/lib/3rdparty/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,13 +50,17 @@ /* read a glyph name and return the equivalent glyph index */ static FT_Int t1_get_index( const char* name, - FT_UInt len, + FT_Offset len, void* user_data ) { T1_Font type1 = (T1_Font)user_data; FT_Int n; + /* PS string/name length must be < 16-bit */ + if ( len > 0xFFFFU ) + return 0; + for ( n = 0; n < type1->num_glyphs; n++ ) { char* gname = (char*)type1->glyph_names[n]; @@ -88,7 +92,12 @@ FT_ULong index2 = KERN_INDEX( pair2->index1, pair2->index2 ); - return (int)( index1 - index2 ); + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; } @@ -276,13 +285,15 @@ { t1_font->font_bbox = fi->FontBBox; - t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; - t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; - t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFFU ) >> 16; - t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFFU ) >> 16; + t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; + t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16; + t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16; - t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000U ) >> 16 ); - t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000U ) >> 16 ); + /* no `U' suffix here to 0x8000! */ + t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 ); + t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 ); if ( fi->NumKernPair ) { diff --git a/lib/3rdparty/freetype/src/type1/t1driver.c b/lib/3rdparty/freetype/src/type1/t1driver.c index 3ca21dc1783..8c398eee228 100644 --- a/lib/3rdparty/freetype/src/type1/t1driver.c +++ b/lib/3rdparty/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -84,6 +84,7 @@ return 0; } + static const FT_Service_GlyphDictRec t1_service_glyph_dict = { (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, @@ -91,10 +92,10 @@ }; - /* - * POSTSCRIPT NAME SERVICE - * - */ + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* t1_get_ps_name( T1_Face face ) @@ -102,16 +103,17 @@ return (const char*) face->type1.font_name; } + static const FT_Service_PsFontNameRec t1_service_ps_name = { (FT_PsName_GetFunc)t1_get_ps_name }; - /* - * MULTIPLE MASTERS SERVICE - * - */ + /* + * MULTIPLE MASTERS SERVICE + * + */ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = @@ -125,17 +127,28 @@ #endif - /* - * POSTSCRIPT INFO SERVICE - * - */ + /* + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error t1_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((T1_Face)face)->type1.font_info; - return 0; + + return T1_Err_Ok; + } + + + static FT_Error + t1_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T1_Face)face)->type1.font_extra; + + return T1_Err_Ok; } @@ -143,6 +156,7 @@ t1_ps_has_glyph_names( FT_Face face ) { FT_UNUSED( face ); + return 1; } @@ -152,17 +166,20 @@ PS_PrivateRec* afont_private ) { *afont_private = ((T1_Face)face)->type1.private_dict; - return 0; + + return T1_Err_Ok; } static const FT_Service_PsInfoRec t1_service_ps_info = { (PS_GetFontInfoFunc) t1_ps_get_font_info, + (PS_GetFontExtraFunc) t1_ps_get_font_extra, (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, (PS_GetFontPrivateFunc)t1_ps_get_font_private, }; + #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { @@ -170,10 +187,11 @@ }; #endif - /* - * SERVICE LIST - * - */ + + /* + * SERVICE LIST + * + */ static const FT_ServiceDescRec t1_services[] = { @@ -304,7 +322,7 @@ (FT_Face_GetKerningFunc) Get_Kerning, (FT_Face_AttachFunc) T1_Read_Metrics, #endif - (FT_Face_GetAdvancesFunc) 0, + (FT_Face_GetAdvancesFunc) T1_Get_Advances, (FT_Size_RequestFunc) T1_Size_Request, (FT_Size_SelectFunc) 0 }; diff --git a/lib/3rdparty/freetype/src/type1/t1driver.h b/lib/3rdparty/freetype/src/type1/t1driver.h index ad429440de9..9fecbeb0f8f 100644 --- a/lib/3rdparty/freetype/src/type1/t1driver.h +++ b/lib/3rdparty/freetype/src/type1/t1driver.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; diff --git a/lib/3rdparty/freetype/src/type1/t1gload.c b/lib/3rdparty/freetype/src/type1/t1gload.c index e08a4289742..f3fad4f5df7 100644 --- a/lib/3rdparty/freetype/src/type1/t1gload.c +++ b/lib/3rdparty/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,6 +18,7 @@ #include #include "t1gload.h" +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H @@ -62,6 +63,11 @@ T1_Font type1 = &face->type1; FT_Error error = T1_Err_Ok; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; +#endif + decoder->font_matrix = type1->font_matrix; decoder->font_offset = type1->font_offset; @@ -70,10 +76,9 @@ /* For incremental fonts get the character data using the */ /* callback function. */ - if ( face->root.internal->incremental_interface ) - error = face->root.internal->incremental_interface->funcs->get_glyph_data( - face->root.internal->incremental_interface->object, - glyph_index, char_string ); + if ( inc ) + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, char_string ); else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -92,22 +97,22 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && face->root.internal->incremental_interface && - face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + if ( !error && inc && inc->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; - metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; - error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( - face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); - decoder->builder.left_bearing.x = metrics.bearing_x; - decoder->builder.left_bearing.y = metrics.bearing_y; - decoder->builder.advance.x = metrics.advance; - decoder->builder.advance.y = 0; + metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); + metrics.bearing_y = 0; + metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); + metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); + + error = inc->funcs->get_glyph_metrics( inc->object, + glyph_index, FALSE, &metrics ); + + decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); + decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); + decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ @@ -202,6 +207,63 @@ } + FT_LOCAL_DEF( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ) + { + T1_DecoderRec decoder; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_UInt nn; + FT_Error error; + + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + for ( nn = 0; nn < count; nn++ ) + advances[nn] = 0; + + return T1_Err_Ok; + } + + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + decoder.buildchar = face->buildchar; + decoder.len_buildchar = face->len_buildchar; + + for ( nn = 0; nn < count; nn++ ) + { + error = T1_Parse_Glyph( &decoder, first + nn ); + if ( !error ) + advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); + else + advances[nn] = 0; + } + + return T1_Err_Ok; + } + + FT_LOCAL_DEF( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, @@ -225,7 +287,12 @@ #endif +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_index >= (FT_UInt)face->root.num_glyphs && + !face->root.internal->incremental_interface ) +#else if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ { error = T1_Err_Invalid_Argument; goto Exit; @@ -236,8 +303,16 @@ if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; + if ( size ) + { + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + } + else + { + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + } glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -303,11 +378,14 @@ FT_Slot_Internal internal = glyph->root.internal; - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - internal->glyph_matrix = font_matrix; - internal->glyph_delta = font_offset; - internal->glyph_transformed = 1; + glyph->root.metrics.horiBearingX = + FIXED_TO_INT( decoder.builder.left_bearing.x ); + glyph->root.metrics.horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; } else { @@ -317,14 +395,26 @@ /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - glyph->root.linearHoriAdvance = decoder.builder.advance.x; + metrics->horiAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); + glyph->root.linearHoriAdvance = + FIXED_TO_INT( decoder.builder.advance.x ); glyph->root.internal->glyph_transformed = 0; - /* make up vertical ones */ - metrics->vertAdvance = ( face->type1.font_bbox.yMax - - face->type1.font_bbox.yMin ) >> 16; - glyph->root.linearVertAdvance = metrics->vertAdvance; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + metrics->vertAdvance = ( face->type1.font_bbox.yMax - + face->type1.font_bbox.yMin ) >> 16; + glyph->root.linearVertAdvance = metrics->vertAdvance; + } + else + { + metrics->vertAdvance = + FIXED_TO_INT( decoder.builder.advance.y ); + glyph->root.linearVertAdvance = + FIXED_TO_INT( decoder.builder.advance.y ); + } glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; @@ -371,8 +461,8 @@ } /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); } /* compute the other metrics */ @@ -384,9 +474,12 @@ metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; - /* make up vertical ones */ - ft_synthesize_vertical_metrics( metrics, - metrics->vertAdvance ); + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + /* make up vertical ones */ + ft_synthesize_vertical_metrics( metrics, + metrics->vertAdvance ); + } } /* Set control data to the glyph charstrings. Note that this is */ diff --git a/lib/3rdparty/freetype/src/type1/t1gload.h b/lib/3rdparty/freetype/src/type1/t1gload.h index de87896dc0e..100df06e8e3 100644 --- a/lib/3rdparty/freetype/src/type1/t1gload.h +++ b/lib/3rdparty/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,13 @@ FT_BEGIN_HEADER T1_Compute_Max_Advance( T1_Face face, FT_Pos* max_advance ); + FT_LOCAL( FT_Error ) + T1_Get_Advances( T1_Face face, + FT_UInt first, + FT_UInt count, + FT_ULong load_flags, + FT_Fixed* advances ); + FT_LOCAL( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, diff --git a/lib/3rdparty/freetype/src/type1/t1load.c b/lib/3rdparty/freetype/src/type1/t1load.c index 55177eed438..d867e942c95 100644 --- a/lib/3rdparty/freetype/src/type1/t1load.c +++ b/lib/3rdparty/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,6 +65,7 @@ #include FT_CONFIG_CONFIG_H #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_CALC_H #include "t1load.h" #include "t1errors.h" @@ -213,10 +214,6 @@ } -#define FT_INT_TO_FIXED( a ) ( (a) << 16 ) -#define FT_FIXED_TO_INT( a ) ( FT_RoundFix( a ) >> 16 ) - - /*************************************************************************/ /* */ /* Given a normalized (blend) coordinate, figure out the design */ @@ -230,7 +227,7 @@ if ( ncv <= axismap->blend_points[0] ) - return axismap->design_points[0]; + return INT_TO_FIXED( axismap->design_points[0] ); for ( j = 1; j < axismap->num_points; ++j ) { @@ -241,8 +238,7 @@ axismap->blend_points[j] - axismap->blend_points[j - 1] ); - - return axismap->design_points[j - 1] + + return INT_TO_FIXED( axismap->design_points[j - 1] ) + FT_MulDiv( t, axismap->design_points[j] - axismap->design_points[j - 1], @@ -250,7 +246,7 @@ } } - return axismap->design_points[axismap->num_points - 1]; + return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] ); } @@ -332,13 +328,13 @@ for ( i = 0 ; i < mmaster.num_axis; ++i ) { mmvar->axis[i].name = mmaster.axis[i].name; - mmvar->axis[i].minimum = FT_INT_TO_FIXED( mmaster.axis[i].minimum); - mmvar->axis[i].maximum = FT_INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].maximum ) / 2; /* Does not apply. But this value is in range */ - mmvar->axis[i].strid = 0xFFFFFFFFUL; /* Does not apply */ - mmvar->axis[i].tag = 0xFFFFFFFFUL; /* Does not apply */ + mmvar->axis[i].strid = (FT_UInt)-1; /* Does not apply */ + mmvar->axis[i].tag = (FT_ULong)-1; /* Does not apply */ if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); @@ -348,16 +344,15 @@ mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); } - if ( blend->num_designs == 1U << blend->num_axis ) + if ( blend->num_designs == ( 1U << blend->num_axis ) ) { mm_weights_unmap( blend->default_weight_vector, axiscoords, blend->num_axis ); for ( i = 0; i < mmaster.num_axis; ++i ) - mmvar->axis[i].def = - FT_INT_TO_FIXED( mm_axis_unmap( &blend->design_map[i], - axiscoords[i] ) ); + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); } *master = mmvar; @@ -504,7 +499,7 @@ if ( num_coords <= 4 && num_coords > 0 ) { for ( i = 0; i < num_coords; ++i ) - lcoords[i] = FT_FIXED_TO_INT( coords[i] ); + lcoords[i] = FIXED_TO_INT( coords[i] ); error = T1_Set_MM_Design( face, num_coords, lcoords ); } @@ -656,8 +651,8 @@ } if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { - FT_ERROR(( "parse_blend_design_positions:" )); - FT_ERROR(( " incorrect number of designs: %d\n", + FT_ERROR(( "parse_blend_design_positions:" + " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; @@ -674,7 +669,7 @@ for ( n = 0; n < num_designs; n++ ) { - T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; T1_Token token; FT_Int axis, n_axis; @@ -687,6 +682,15 @@ if ( n == 0 ) { + if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_positions:" + " invalid number of axes: %d\n", + n_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + num_axis = n_axis; error = t1_allocate_blend( face, num_designs, num_axis ); if ( error ) @@ -835,8 +839,8 @@ } if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { - FT_ERROR(( "parse_weight_vector:" )); - FT_ERROR(( " incorrect number of designs: %d\n", + FT_ERROR(( "parse_weight_vector:" + " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; @@ -852,9 +856,9 @@ else if ( blend->num_designs != (FT_UInt)num_designs ) { FT_ERROR(( "parse_weight_vector:" - " /BlendDesignPosition and /WeightVector have\n" )); - FT_ERROR(( " " - " different number of elements!\n" )); + " /BlendDesignPosition and /WeightVector have\n" + " " + " different number of elements\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -941,6 +945,12 @@ } break; + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + objects = &dummy_object; + max_objects = 0; + break; + case T1_FIELD_LOCATION_PRIVATE: dummy_object = &face->type1.private_dict; objects = &dummy_object; @@ -1130,7 +1140,7 @@ cur = parser->root.cursor; if ( cur >= limit ) { - FT_ERROR(( "parse_encoding: out of bounds!\n" )); + FT_ERROR(( "parse_encoding: out of bounds\n" )); parser->root.error = T1_Err_Invalid_File_Format; return; } @@ -1265,6 +1275,19 @@ n++; } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the type1 */ + /* specification (it might be an encoding for a CID type1 */ + /* font, however), so we conclude that this font is NOT a */ + /* type1 font. */ + parser->root.error = FT_Err_Unknown_File_Format; + return; + } } else { @@ -1310,9 +1333,9 @@ PS_Table table = &loader->subrs; FT_Memory memory = parser->root.memory; FT_Error error; - FT_Int n, num_subrs; + FT_Int num_subrs; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)face->psaux; T1_Skip_Spaces( parser ); @@ -1346,18 +1369,17 @@ goto Fail; } - /* the format is simple: */ - /* */ - /* `index' + binary data */ - /* */ - for ( n = 0; n < num_subrs; n++ ) + /* the format is simple: */ + /* */ + /* `index' + binary data */ + /* */ + for (;;) { FT_Long idx, size; FT_Byte* base; - /* If the next token isn't `dup', we are also done. This */ - /* happens when there are `holes' in the Subrs array. */ + /* If the next token isn't `dup' we are done. */ if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) break; @@ -1397,7 +1419,10 @@ FT_Byte* temp; - if ( size <= face->type1.private_dict.lenIV ) + /* some fonts define empty subr records -- this is not totally */ + /* compliant to the specification (which says they should at */ + /* least contain a `return'), but we support them anyway */ + if ( size < face->type1.private_dict.lenIV ) { error = T1_Err_Invalid_File_Format; goto Fail; @@ -1603,15 +1628,11 @@ } } - if ( loader->num_glyphs ) - return; - else - loader->num_glyphs = n; + loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)name_table->elements[0] ) && - notdef_found ) + if ( notdef_found && + ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) { /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ /* name and code entries to swap_table. Then place notdef_index */ @@ -1680,7 +1701,7 @@ /* and add our own /.notdef glyph to index 0. */ /* 0 333 hsbw endchar */ - FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; + FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; char* notdef_name = (char *)".notdef"; @@ -1718,7 +1739,7 @@ goto Fail; /* we added a glyph. */ - loader->num_glyphs = n + 1; + loader->num_glyphs += 1; } return; @@ -2132,7 +2153,7 @@ #endif if ( !loader.charstrings.init ) { - FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" )); + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); error = T1_Err_Invalid_File_Format; } @@ -2161,8 +2182,8 @@ /* the index is then stored in type1.encoding.char_index, and */ /* a the name to type1.encoding.char_name */ - min_char = +32000; - max_char = -32000; + min_char = 0; + max_char = 0; charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) @@ -2188,25 +2209,14 @@ { if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) - max_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; } break; } } } - /* - * Yes, this happens: Certain PDF-embedded fonts have only a - * `.notdef' glyph defined! - */ - - if ( min_char > max_char ) - { - min_char = 0; - max_char = loader.encoding_table.max_elems; - } - type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; diff --git a/lib/3rdparty/freetype/src/type1/t1objs.c b/lib/3rdparty/freetype/src/type1/t1objs.c index 3d08336c600..b1de6871967 100644 --- a/lib/3rdparty/freetype/src/type1/t1objs.c +++ b/lib/3rdparty/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_IDS_H @@ -90,7 +91,7 @@ FT_LOCAL_DEF( FT_Error ) T1_Size_Init( T1_Size size ) { - FT_Error error = 0; + FT_Error error = T1_Err_Ok; PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); @@ -191,72 +192,75 @@ FT_LOCAL_DEF( void ) T1_Face_Done( T1_Face face ) { - if ( face ) - { - FT_Memory memory = face->root.memory; - T1_Font type1 = &face->type1; + FT_Memory memory; + T1_Font type1; + if ( !face ) + return; + + memory = face->root.memory; + type1 = &face->type1; + #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - /* release multiple masters information */ - FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); + /* release multiple masters information */ + FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); - if ( face->buildchar ) - { - FT_FREE( face->buildchar ); + if ( face->buildchar ) + { + FT_FREE( face->buildchar ); - face->buildchar = NULL; - face->len_buildchar = 0; - } + face->buildchar = NULL; + face->len_buildchar = 0; + } - T1_Done_Blend( face ); - face->blend = 0; + T1_Done_Blend( face ); + face->blend = 0; #endif - /* release font info strings */ - { - PS_FontInfo info = &type1->font_info; + /* release font info strings */ + { + PS_FontInfo info = &type1->font_info; - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); - } + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + } - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); - FT_FREE( type1->subrs ); - FT_FREE( type1->subrs_len ); + FT_FREE( type1->subrs ); + FT_FREE( type1->subrs_len ); - FT_FREE( type1->subrs_block ); - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); + FT_FREE( type1->subrs_block ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); #ifndef T1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); #endif - /* release unicode map, if any */ + /* release unicode map, if any */ #if 0 - FT_FREE( face->unicode_map_rec.maps ); - face->unicode_map_rec.num_maps = 0; - face->unicode_map = NULL; + FT_FREE( face->unicode_map_rec.maps ); + face->unicode_map_rec.num_maps = 0; + face->unicode_map = NULL; #endif - face->root.family_name = 0; - face->root.style_name = 0; - } + face->root.family_name = NULL; + face->root.style_name = NULL; } @@ -298,7 +302,6 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); @@ -324,7 +327,7 @@ goto Exit; /* check the face index */ - if ( face_index != 0 ) + if ( face_index > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = T1_Err_Invalid_Argument; @@ -341,7 +344,7 @@ root->num_glyphs = type1->num_glyphs; - root->face_index = face_index; + root->face_index = 0; root->face_flags = FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | @@ -356,11 +359,18 @@ /* XXX: TODO -- add kerning with .afm support */ + + /* The following code to extract the family and the style is very */ + /* simplistic and might get some things wrong. For a full-featured */ + /* algorithm you might have a look at the whitepaper given at */ + /* */ + /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ + /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = info->family_name; - /* assume "Regular" style if we don't know better */ - root->style_name = (char *)"Regular"; + root->style_name = NULL; + if ( root->family_name ) { char* full = info->full_name; @@ -369,6 +379,9 @@ if ( full ) { + FT_Bool the_same = TRUE; + + while ( *full ) { if ( *full == *family ) @@ -384,12 +397,17 @@ family++; else { + the_same = FALSE; + if ( !*family ) root->style_name = full; break; } } } + + if ( the_same ) + root->style_name = (char *)"Regular"; } } else @@ -399,6 +417,15 @@ root->family_name = type1->font_name; } + if ( !root->style_name ) + { + if ( info->weight ) + root->style_name = info->weight; + else + /* assume `Regular' style because we don't know better */ + root->style_name = (char *)"Regular"; + } + /* compute style flags */ root->style_flags = 0; if ( info->italic_angle ) @@ -414,10 +441,11 @@ root->num_fixed_sizes = 0; root->available_sizes = 0; - root->bbox.xMin = type1->font_bbox.xMin >> 16; - root->bbox.yMin = type1->font_bbox.yMin >> 16; - root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFFU ) >> 16; - root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFFU ) >> 16; + root->bbox.xMin = type1->font_bbox.xMin >> 16; + root->bbox.yMin = type1->font_bbox.yMin >> 16; + /* no `U' suffix here to 0xFFFF! */ + root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; + root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; /* Set units_per_EM if we didn't set it in parse_font_matrix. */ if ( !root->units_per_EM ) @@ -441,9 +469,9 @@ /* in case of error, keep the standard width */ if ( !error ) - root->max_advance_width = (FT_Short)max_advance; + root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); else - error = 0; /* clear error */ + error = T1_Err_Ok; /* clear error */ } root->max_advance_height = root->height; @@ -465,7 +493,7 @@ charmap.face = root; - /* first of all, try to synthetize a Unicode charmap */ + /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; diff --git a/lib/3rdparty/freetype/src/type1/t1parse.c b/lib/3rdparty/freetype/src/type1/t1parse.c index 1b252c74833..2a762279fd3 100644 --- a/lib/3rdparty/freetype/src/type1/t1parse.c +++ b/lib/3rdparty/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,7 +35,6 @@ #include #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_POSTSCRIPT_AUX_H @@ -65,14 +64,16 @@ /*************************************************************************/ + /* see Adobe Technical Note 5040.Download_Fonts.pdf */ + static FT_Error read_pfb_tag( FT_Stream stream, FT_UShort *atag, - FT_Long *asize ) + FT_ULong *asize ) { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; *atag = 0; @@ -82,7 +83,7 @@ { if ( tag == 0x8001U || tag == 0x8002U ) { - if ( !FT_READ_LONG_LE( size ) ) + if ( !FT_READ_ULONG_LE( size ) ) *asize = size; } @@ -100,22 +101,25 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong dummy; if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - error = read_pfb_tag( stream, &tag, &size ); + error = read_pfb_tag( stream, &tag, &dummy ); if ( error ) goto Exit; + /* We assume that the first segment in a PFB is always encoded as */ + /* text. This might be wrong (and the specification doesn't insist */ + /* on that), but we have never seen a counterexample. */ if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) goto Exit; if ( !FT_FRAME_ENTER( header_length ) ) { - error = 0; + error = T1_Err_Ok; if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) error = T1_Err_Unknown_File_Format; @@ -136,7 +140,7 @@ { FT_Error error; FT_UShort tag; - FT_Long size; + FT_ULong size; psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); @@ -170,19 +174,19 @@ /* Here a short summary of what is going on: */ /* */ /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e. for PFB */ + /* the base dictionary if this is possible (i.e., for PFB */ /* files). Otherwise, we load the whole font into memory. */ /* */ /* When `loading' the base dictionary, we only setup pointers */ /* in the case of a memory-based stream. Otherwise, we */ /* allocate and load the base dictionary in it. */ /* */ - /* parser->in_pfb is set if we are in a binary (".pfb") font. */ + /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ /* parser->in_memory is set if we have a memory stream. */ /* */ - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e 0x8001 */ + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e., 0x8001 */ if ( FT_STREAM_SEEK( 0L ) ) goto Exit; @@ -217,7 +221,7 @@ } else { - /* read segment in memory - this is clumsy, but so does the format */ + /* read segment in memory -- this is clumsy, but so does the format */ if ( FT_ALLOC( parser->base_dict, size ) || FT_STREAM_READ( parser->base_dict, size ) ) goto Exit; @@ -260,7 +264,7 @@ FT_Stream stream = parser->stream; FT_Memory memory = parser->root.memory; FT_Error error = T1_Err_Ok; - FT_Long size; + FT_ULong size; if ( parser->in_pfb ) @@ -293,13 +297,13 @@ /* and allocate private dictionary buffer */ if ( parser->private_len == 0 ) { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); error = T1_Err_Invalid_File_Format; goto Fail; } - if ( FT_STREAM_SEEK( start_pos ) || + if ( FT_STREAM_SEEK( start_pos ) || FT_ALLOC( parser->private_dict, parser->private_len ) ) goto Fail; @@ -349,8 +353,8 @@ cur++; if ( cur >= limit ) { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " could not find `eexec' keyword\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " could not find `eexec' keyword\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -393,23 +397,26 @@ T1_Skip_PS_Token( parser ); cur = parser->root.cursor; - if ( *cur == '\r' ) + + /* according to the Type1 spec, the first cipher byte must not be */ + /* an ASCII whitespace character code (blank, tab, carriage return */ + /* or line feed). We have seen Type 1 fonts with two line feed */ + /* characters... So skip now all whitespace character codes. */ + while ( cur < limit && + ( *cur == ' ' || + *cur == '\t' || + *cur == '\r' || + *cur == '\n' ) ) + ++cur; + if ( cur >= limit ) { - cur++; - if ( *cur == '\n' ) - cur++; - } - else if ( *cur == '\n' ) - cur++; - else - { - FT_ERROR(( "T1_Get_Private_Dict:" )); - FT_ERROR(( " `eexec' not properly terminated\n" )); + FT_ERROR(( "T1_Get_Private_Dict:" + " `eexec' not properly terminated\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } - size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); + size = parser->base_len - ( cur - parser->base_dict ); if ( parser->in_memory ) { diff --git a/lib/3rdparty/freetype/src/type1/t1parse.h b/lib/3rdparty/freetype/src/type1/t1parse.h index 6fa4ca624a2..fb1c8a88308 100644 --- a/lib/3rdparty/freetype/src/type1/t1parse.h +++ b/lib/3rdparty/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2008 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -64,10 +64,10 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* base_dict; - FT_Long base_len; + FT_ULong base_len; FT_Byte* private_dict; - FT_Long private_len; + FT_ULong private_len; FT_Bool in_pfb; FT_Bool in_memory; diff --git a/lib/3rdparty/freetype/src/type1/t1tokens.h b/lib/3rdparty/freetype/src/type1/t1tokens.h index 788c811b049..2d692f0e619 100644 --- a/lib/3rdparty/freetype/src/type1/t1tokens.h +++ b/lib/3rdparty/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,6 +42,13 @@ T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, T1_FIELD_DICT_FONTDICT ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, + T1_FIELD_DICT_FONTDICT ) #undef FT_STRUCTURE #define FT_STRUCTURE PS_PrivateRec @@ -87,7 +94,9 @@ T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor, T1_FIELD_DICT_PRIVATE ) - + T1_FIELD_BOOL ( "ForceBold", force_bold, + T1_FIELD_DICT_PRIVATE ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec diff --git a/lib/3rdparty/freetype/src/type42/module.mk b/lib/3rdparty/freetype/src/type42/module.mk index 8bd40a5cc49..b3f10a8d3c8 100644 --- a/lib/3rdparty/freetype/src/type42/module.mk +++ b/lib/3rdparty/freetype/src/type42/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += TYPE42_DRIVER define TYPE42_DRIVER -$(OPEN_DRIVER)t42_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, t42_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/type42/rules.mk b/lib/3rdparty/freetype/src/type42/rules.mk index 55630619554..eac1081eb1f 100644 --- a/lib/3rdparty/freetype/src/type42/rules.mk +++ b/lib/3rdparty/freetype/src/type42/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002, 2003 by +# Copyright 2002, 2003, 2008 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -32,7 +32,8 @@ T42_DRV_SRC := $(T42_DIR)/t42objs.c \ # Type42 driver headers # T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ - $(T42_DIR)/t42error.h + $(T42_DIR)/t42error.h \ + $(T42_DIR)/t42types.h # Type42 driver object(s) diff --git a/lib/3rdparty/freetype/src/type42/t42drivr.c b/lib/3rdparty/freetype/src/type42/t42drivr.c index a6e4cf4b651..820c679612e 100644 --- a/lib/3rdparty/freetype/src/type42/t42drivr.c +++ b/lib/3rdparty/freetype/src/type42/t42drivr.c @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2006, 2007, 2009 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -49,11 +49,11 @@ #define FT_COMPONENT trace_t42 - /* - * - * GLYPH DICT SERVICE - * - */ + /* + * + * GLYPH DICT SERVICE + * + */ static FT_Error t42_get_glyph_name( T42_Face face, @@ -94,11 +94,11 @@ }; - /* - * - * POSTSCRIPT NAME SERVICE - * - */ + /* + * + * POSTSCRIPT NAME SERVICE + * + */ static const char* t42_get_ps_font_name( T42_Face face ) @@ -113,17 +113,28 @@ }; - /* - * - * POSTSCRIPT INFO SERVICE - * - */ + /* + * + * POSTSCRIPT INFO SERVICE + * + */ static FT_Error t42_ps_get_font_info( FT_Face face, PS_FontInfoRec* afont_info ) { *afont_info = ((T42_Face)face)->type1.font_info; + + return T42_Err_Ok; + } + + + static FT_Error + t42_ps_get_font_extra( FT_Face face, + PS_FontExtraRec* afont_extra ) + { + *afont_extra = ((T42_Face)face)->type1.font_extra; + return T42_Err_Ok; } @@ -132,6 +143,7 @@ t42_ps_has_glyph_names( FT_Face face ) { FT_UNUSED( face ); + return 1; } @@ -141,6 +153,7 @@ PS_PrivateRec* afont_private ) { *afont_private = ((T42_Face)face)->type1.private_dict; + return T42_Err_Ok; } @@ -148,16 +161,17 @@ static const FT_Service_PsInfoRec t42_service_ps_info = { (PS_GetFontInfoFunc) t42_ps_get_font_info, + (PS_GetFontExtraFunc) t42_ps_get_font_extra, (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, (PS_GetFontPrivateFunc)t42_ps_get_font_private }; - /* - * - * SERVICE LIST - * - */ + /* + * + * SERVICE LIST + * + */ static const FT_ServiceDescRec t42_services[] = { diff --git a/lib/3rdparty/freetype/src/type42/t42drivr.h b/lib/3rdparty/freetype/src/type42/t42drivr.h index 98b7410b670..4717e4613f3 100644 --- a/lib/3rdparty/freetype/src/type42/t42drivr.h +++ b/lib/3rdparty/freetype/src/type42/t42drivr.h @@ -25,6 +25,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; diff --git a/lib/3rdparty/freetype/src/type42/t42objs.c b/lib/3rdparty/freetype/src/type42/t42objs.c index db04fde367a..9081ffc6d22 100644 --- a/lib/3rdparty/freetype/src/type42/t42objs.c +++ b/lib/3rdparty/freetype/src/type42/t42objs.c @@ -4,7 +4,8 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ +/* by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -19,7 +20,6 @@ #include "t42parse.h" #include "t42error.h" #include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H #include FT_LIST_H @@ -70,7 +70,7 @@ if ( !loader.charstrings.init ) { - FT_ERROR(( "T42_Open_Face: no charstrings array in face!\n" )); + FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" )); error = T42_Err_Invalid_File_Format; } @@ -100,8 +100,8 @@ /* The index is then stored in type1.encoding.char_index, and */ /* the name in type1.encoding.char_name */ - min_char = +32000; - max_char = -32000; + min_char = 0; + max_char = 0; charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) @@ -127,13 +127,14 @@ { if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) - max_char = charcode; + if ( charcode >= max_char ) + max_char = charcode + 1; } break; } } } + type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; @@ -188,7 +189,7 @@ goto Exit; /* check the face index */ - if ( face_index != 0 ) + if ( face_index > 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = T42_Err_Invalid_Argument; @@ -202,7 +203,7 @@ root->num_glyphs = type1->num_glyphs; root->num_charmaps = 0; - root->face_index = face_index; + root->face_index = 0; root->face_flags = FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | @@ -328,7 +329,7 @@ charmap.face = root; - /* first of all, try to synthetize a Unicode charmap */ + /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; @@ -392,50 +393,50 @@ FT_Memory memory; - if ( face ) - { - type1 = &face->type1; - info = &type1->font_info; - memory = face->root.memory; + if ( !face ) + return; - /* delete internal ttf face prior to freeing face->ttf_data */ - if ( face->ttf_face ) - FT_Done_Face( face->ttf_face ); + type1 = &face->type1; + info = &type1->font_info; + memory = face->root.memory; - /* release font info strings */ - FT_FREE( info->version ); - FT_FREE( info->notice ); - FT_FREE( info->full_name ); - FT_FREE( info->family_name ); - FT_FREE( info->weight ); + /* delete internal ttf face prior to freeing face->ttf_data */ + if ( face->ttf_face ) + FT_Done_Face( face->ttf_face ); - /* release top dictionary */ - FT_FREE( type1->charstrings_len ); - FT_FREE( type1->charstrings ); - FT_FREE( type1->glyph_names ); + /* release font info strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); - FT_FREE( type1->charstrings_block ); - FT_FREE( type1->glyph_names_block ); + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); - FT_FREE( type1->encoding.char_index ); - FT_FREE( type1->encoding.char_name ); - FT_FREE( type1->font_name ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); - FT_FREE( face->ttf_data ); + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + + FT_FREE( face->ttf_data ); #if 0 - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); #endif - /* release unicode map, if any */ - FT_FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; + /* release unicode map, if any */ + FT_FREE( face->unicode_map.maps ); + face->unicode_map.num_maps = 0; - face->root.family_name = 0; - face->root.style_name = 0; - } + face->root.family_name = 0; + face->root.style_name = 0; } @@ -519,7 +520,7 @@ FT_Activate_Size( size->ttsize ); - error = FT_Select_Size( face->ttf_face, strike_index ); + error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index ); if ( !error ) ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; diff --git a/lib/3rdparty/freetype/src/type42/t42parse.c b/lib/3rdparty/freetype/src/type42/t42parse.c index 7148379644f..13bda64c837 100644 --- a/lib/3rdparty/freetype/src/type42/t42parse.c +++ b/lib/3rdparty/freetype/src/type42/t42parse.c @@ -4,7 +4,8 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ +/* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -19,7 +20,6 @@ #include "t42error.h" #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H -#include FT_LIST_H #include FT_INTERNAL_POSTSCRIPT_AUX_H @@ -69,6 +69,13 @@ T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 ) T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 ) +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontExtraRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA + + T1_FIELD_NUM ( "FSType", fs_type, 0 ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec #undef T1CODE @@ -296,7 +303,7 @@ cur = parser->root.cursor; if ( cur >= limit ) { - FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); + FT_ERROR(( "t42_parse_encoding: out of bounds\n" )); parser->root.error = T42_Err_Invalid_File_Format; return; } @@ -464,14 +471,14 @@ else { - FT_ERROR(( "t42_parse_encoding: invalid token!\n" )); + FT_ERROR(( "t42_parse_encoding: invalid token\n" )); parser->root.error = T42_Err_Invalid_File_Format; } } } - typedef enum + typedef enum T42_Load_Status_ { BEFORE_START, BEFORE_TABLE_DIR, @@ -517,7 +524,7 @@ if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) { - FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector!\n" )); + FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -562,7 +569,7 @@ if ( allocated ) { FT_ERROR(( "t42_parse_sfnts: " - "can't handle mixed binary and hex strings!\n" )); + "can't handle mixed binary and hex strings\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -578,7 +585,7 @@ parser->root.cursor += string_size + 1; if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data!\n" )); + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -586,7 +593,7 @@ if ( !string_buf ) { - FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array!\n" )); + FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -597,7 +604,7 @@ if ( !string_size ) { - FT_ERROR(( "t42_parse_sfnts: invalid string!\n" )); + FT_ERROR(( "t42_parse_sfnts: invalid string\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -662,7 +669,7 @@ /* all other tables are just copied */ if ( count >= ttf_size ) { - FT_ERROR(( "t42_parse_sfnts: too many binary data!\n" )); + FT_ERROR(( "t42_parse_sfnts: too many binary data\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -709,7 +716,7 @@ if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -751,14 +758,14 @@ } else { - FT_ERROR(( "t42_parse_charstrings: invalid token!\n" )); + FT_ERROR(( "t42_parse_charstrings: invalid token\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -818,7 +825,7 @@ if ( cur + 1 >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -849,7 +856,7 @@ (void)T1_ToInt( parser ); if ( parser->root.cursor >= limit ) { - FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -872,7 +879,7 @@ if ( !notdef_found ) { - FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph!\n" )); + FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } @@ -976,6 +983,10 @@ dummy_object = &face->type1.font_info; break; + case T1_FIELD_LOCATION_FONT_EXTRA: + dummy_object = &face->type1.font_extra; + break; + case T1_FIELD_LOCATION_BBOX: dummy_object = &face->type1.font_bbox; break; diff --git a/lib/3rdparty/freetype/src/type42/t42types.h b/lib/3rdparty/freetype/src/type42/t42types.h index 6626b04458a..c7c2db490df 100644 --- a/lib/3rdparty/freetype/src/type42/t42types.h +++ b/lib/3rdparty/freetype/src/type42/t42types.h @@ -4,7 +4,7 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002, 2003, 2006 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2006, 2008 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -35,7 +35,9 @@ FT_BEGIN_HEADER T1_FontRec type1; const void* psnames; const void* psaux; +#if 0 const void* afm_data; +#endif FT_Byte* ttf_data; FT_ULong ttf_size; FT_Face ttf_face; @@ -48,7 +50,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TYPES_H__ */ +#endif /* __T42TYPES_H__ */ /* END */ diff --git a/lib/3rdparty/freetype/src/winfonts/module.mk b/lib/3rdparty/freetype/src/winfonts/module.mk index 0ace3ae6de0..b44d7f0570a 100644 --- a/lib/3rdparty/freetype/src/winfonts/module.mk +++ b/lib/3rdparty/freetype/src/winfonts/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += WINDOWS_DRIVER define WINDOWS_DRIVER -$(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER) +$(OPEN_DRIVER) FT_Driver_ClassRec, winfnt_driver_class $(CLOSE_DRIVER) $(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) endef diff --git a/lib/3rdparty/freetype/src/winfonts/winfnt.c b/lib/3rdparty/freetype/src/winfonts/winfnt.c index 4aa974410f3..6b3a4e17f20 100644 --- a/lib/3rdparty/freetype/src/winfonts/winfnt.c +++ b/lib/3rdparty/freetype/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2003 Huw D M Davies for Codeweavers */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ @@ -342,7 +342,7 @@ if ( !font_count || !font_offset ) { - FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); + FT_TRACE2(( "this file doesn't contain any FNT resources\n" )); error = FNT_Err_Invalid_File_Format; goto Exit; } @@ -360,9 +360,11 @@ if ( face_index >= font_count ) { - error = FNT_Err_Bad_Argument; + error = FNT_Err_Invalid_Argument; goto Exit; } + else if ( face_index < 0 ) + goto Exit; if ( FT_NEW( face->font ) ) goto Exit; @@ -564,7 +566,7 @@ if ( face_index >= face->root.num_faces ) { - error = FNT_Err_Bad_Argument; + error = FNT_Err_Invalid_Argument; goto Exit; } } @@ -610,13 +612,14 @@ char_code -= cmap->first; if ( char_code < cmap->count ) - gindex = char_code + 1; /* we artificially increase the glyph index; */ - /* FNT_Load_Glyph reverts to the right one */ + /* we artificially increase the glyph index; */ + /* FNT_Load_Glyph reverts to the right one */ + gindex = (FT_UInt)( char_code + 1 ); return gindex; } - static FT_UInt + static FT_UInt32 fnt_cmap_char_next( FNT_CMap cmap, FT_UInt32 *pchar_code ) { @@ -636,7 +639,7 @@ if ( char_code < cmap->count ) { result = cmap->first + char_code; - gindex = char_code + 1; + gindex = (FT_UInt)( char_code + 1 ); } } @@ -652,7 +655,9 @@ (FT_CMap_InitFunc) fnt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)fnt_cmap_char_index, - (FT_CMap_CharNextFunc) fnt_cmap_char_next + (FT_CMap_CharNextFunc) fnt_cmap_char_next, + + NULL, NULL, NULL, NULL, NULL }; static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; @@ -661,16 +666,18 @@ static void FNT_Face_Done( FNT_Face face ) { - if ( face ) - { - FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Memory memory; - fnt_font_done( face ); + if ( !face ) + return; - FT_FREE( face->root.available_sizes ); - face->root.num_fixed_sizes = 0; - } + memory = FT_FACE_MEMORY( face ); + + fnt_font_done( face ); + + FT_FREE( face->root.available_sizes ); + face->root.num_fixed_sizes = 0; } @@ -690,18 +697,14 @@ /* try to load font from a DLL */ error = fnt_face_get_dll_font( face, face_index ); + if ( !error && face_index < 0 ) + goto Exit; + if ( error == FNT_Err_Unknown_File_Format ) { /* this didn't work; try to load a single FNT font */ FNT_Font font; - - if ( face_index > 0 ) - { - error = FNT_Err_Bad_Argument; - goto Exit; - } - if ( FT_NEW( face->font ) ) goto Exit; @@ -712,6 +715,14 @@ font->fnt_size = stream->size; error = fnt_font_load( font, stream ); + + if ( !error ) + { + if ( face_index > 0 ) + error = FNT_Err_Invalid_Argument; + else if ( face_index < 0 ) + goto Exit; + } } if ( error ) @@ -725,6 +736,8 @@ FT_PtrDist family_size; + root->face_index = face_index; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL; @@ -772,7 +785,7 @@ * => nominal_point_size contains incorrect value; * use pixel_height as the nominal height */ - if ( bsize->y_ppem > font->header.pixel_height << 6 ) + if ( bsize->y_ppem > ( font->header.pixel_height << 6 ) ) { FT_TRACE2(( "use pixel_height as the nominal height\n" )); @@ -820,7 +833,7 @@ if ( font->header.face_name_offset >= font->header.file_size ) { - FT_TRACE2(( "invalid family name offset!\n" )); + FT_TRACE2(( "invalid family name offset\n" )); error = FNT_Err_Invalid_File_Format; goto Fail; } @@ -901,7 +914,7 @@ switch ( req->type ) { case FT_SIZE_REQUEST_TYPE_NOMINAL: - if ( height == ( bsize->y_ppem + 32 ) >> 6 ) + if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) error = FNT_Err_Ok; break; @@ -967,7 +980,7 @@ if ( offset >= font->header.file_size ) { - FT_TRACE2(( "invalid FNT offset!\n" )); + FT_TRACE2(( "invalid FNT offset\n" )); error = FNT_Err_Invalid_File_Format; goto Exit; } diff --git a/lib/3rdparty/freetype/src/winfonts/winfnt.h b/lib/3rdparty/freetype/src/winfonts/winfnt.h index ca75c9501a2..70a90861abf 100644 --- a/lib/3rdparty/freetype/src/winfonts/winfnt.h +++ b/lib/3rdparty/freetype/src/winfonts/winfnt.h @@ -28,6 +28,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + typedef struct WinMZ_HeaderRec_ { FT_UShort magic; diff --git a/lib/3rdparty/zlib/ChangeLog b/lib/3rdparty/zlib/ChangeLog index 7f6869d3235..f310bb0fcdb 100644 --- a/lib/3rdparty/zlib/ChangeLog +++ b/lib/3rdparty/zlib/ChangeLog @@ -1,6 +1,359 @@ ChangeLog file for zlib +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling error in zlib.h [Willem] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + Changes in 1.2.3 (18 July 2005) - Apply security vulnerability fixes to contrib/infback9 as well - Clean up some text files (carriage returns, trailing space) @@ -13,7 +366,7 @@ Changes in 1.2.2.4 (11 July 2005) compile - Fix some spelling errors in comments [Betts] - Correct inflateInit2() error return documentation in zlib.h -- Added zran.c example of compressed data random access to examples +- Add zran.c example of compressed data random access to examples directory, shows use of inflatePrime() - Fix cast for assignments to strm->state in inflate.c and infback.c - Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] diff --git a/lib/3rdparty/zlib/FAQ b/lib/3rdparty/zlib/FAQ index 441d910daa1..1a22750a58e 100644 --- a/lib/3rdparty/zlib/FAQ +++ b/lib/3rdparty/zlib/FAQ @@ -3,8 +3,8 @@ If your question is not there, please check the zlib home page -http://www.zlib.org which may have more recent information. -The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html +http://zlib.net/ which may have more recent information. +The lastest zlib FAQ is at http://zlib.net/zlib_faq.html 1. Is zlib Y2K-compliant? @@ -13,54 +13,51 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 2. Where can I get a Windows DLL version? - The zlib sources can be compiled without change to produce a DLL. - See the file win32/DLL_FAQ.txt in the zlib distribution. - Pointers to the precompiled DLL are found in the zlib web site at - http://www.zlib.org. + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at http://zlib.net/ . 3. Where can I get a Visual Basic interface to zlib? See - * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm - * contrib/visual-basic.txt in the zlib distribution + * http://marknelson.us/1997/01/01/zlib-engine/ * win32/DLL_FAQ.txt in the zlib distribution 4. compress() returns Z_BUF_ERROR. - Make sure that before the call of compress, the length of the compressed - buffer is equal to the total size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference ("as any"), not by value ("as long"). 5. deflate() or inflate() returns Z_BUF_ERROR. - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a + heavily annotated example. 6. Where's the zlib documentation (man pages, etc.)? - It's in zlib.h for the moment, and Francis S. Lin has converted it to a - web page zlib.html. Volunteers to transform this to Unix-style man pages, - please contact us (zlib@gzip.org). Examples of zlib usage are in the files - example.c and minigzip.c. + It's in zlib.h . Examples of zlib usage are in the files example.c and + minigzip.c, with more in examples/ . 7. Why don't you use GNU autoconf or libtool or ...? - Because we would like to keep zlib as a very small and simple - package. zlib is rather portable and doesn't need much configuration. + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. 8. I found a bug in zlib. - Most of the time, such problems are due to an incorrect usage of - zlib. Please try to reproduce the problem with a small program and send - the corresponding source to us at zlib@gzip.org . Do not send - multi-megabyte data files without prior agreement. + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. 9. Why do I get "undefined reference to gzputc"? @@ -82,7 +79,7 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 12. Can zlib handle .Z files? - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt the code of uncompress on your own. 13. How can I make a Unix shared library? @@ -99,8 +96,10 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html However, many flavors of Unix come with a shared zlib already installed. Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to it. + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . 15. I have a question about OttoPDF. @@ -109,8 +108,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 16. Can zlib decode Flate data in an Adobe PDF file? - Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . - To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . + Yes. See http://www.pdflib.com/ . To modify PDF forms, see + http://sourceforge.net/projects/acroformtool/ . 17. Why am I getting this "register_frame_info not found" error on Solaris? @@ -121,67 +120,67 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html symbol __register_frame_info: referenced symbol not found The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See http://www.sunfreeware.com for Solaris versions of zlib and applications using zlib. 18. Why does gzip give an error on a file I make with compress/deflate? The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip - formats use the same compressed data format internally, but have different - headers and trailers around the compressed data. + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. 19. Ok, so why are there two different formats? - The gzip format was designed to retain the directory information about - a single file, such as the name and last modification date. The zlib - format on the other hand was designed for in-memory and communication - channel applications, and has a much more compact header and trailer and - uses a faster integrity check than gzip. + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. 20. Well that's nice, but how do I make a gzip file in memory? You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode - the gzip format using inflateInit2(). Read zlib.h for more details. + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. 21. Is zlib thread-safe? - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's Init functions allow - for the application to provide custom memory allocation routines. + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. Of course, you should only operate on any given zlib or gzip stream from a single thread at a time. 22. Can I use zlib in my commercial application? - Yes. Please read the license in zlib.h. + Yes. Please read the license in zlib.h. 23. Is zlib under the GNU license? - No. Please read the license in zlib.h. + No. Please read the license in zlib.h. 24. The license says that altered source versions must be "plainly marked". So what exactly do I need to do to meet that requirement? - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers + identification string should be appended to ZLIB_VERSION. Version numbers x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering + maintainers. For example, if the version of the base zlib you are altering is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also update the version strings in deflate.c and inftrees.c. For altered source distributions, you should also note the origin and nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your + with the dates of the alterations. The origin should include at least your name (or your company's name), and an email address to contact for help or issues with the library. @@ -197,105 +196,112 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 26. Will zlib work on a 64-bit machine? - It should. It has been tested on 64-bit machines, and has no dependence - on any data types being limited to 32-bits in length. If you have any + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any difficulties, please provide a complete problem report to zlib@gzip.org 27. Will zlib decompress data from the PKWare Data Compression Library? - No. The PKWare DCL uses a completely different compressed data format - than does PKZIP and zlib. However, you can look in zlib's contrib/blast + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast directory for a possible solution to your problem. 28. Can I access data randomly in a compressed stream? - No, not without some preparation. If when compressing you periodically - use Z_FULL_FLUSH, carefully write all the pending data at those points, - and keep an index of those locations, then you can start decompression - at those points. You have to be careful to not use Z_FULL_FLUSH too - often, since it can significantly degrade compression. + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . 29. Does zlib work on MVS, OS/390, CICS, etc.? - We don't know for sure. We have heard occasional reports of success on - these systems. If you do use it on one of these, please provide us with - a report, instructions, and patches that we can reference when we get - these questions. Thanks. + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. -30. Is there some simpler, easier to read version of inflate I can look at - to understand the deflate format? +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? - First off, you should read RFC 1951. Second, yes. Look in zlib's + First off, you should read RFC 1951. Second, yes. Look in zlib's contrib/puff directory. 31. Does zlib infringe on any patents? - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: http://www.gzip.org/#faq11 32. Can zlib work with greater than 4 GB of data? - Yes. inflate() and deflate() will process any amount of data correctly. + Yes. inflate() and deflate() will process any amount of data correctly. Each call of inflate() or deflate() is limited to input and output chunks of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters + inflate() or deflate(). The application can easily set up its own counters updated after each call of inflate() or deflate() to count beyond 4 GB. compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. - The word "may" appears several times above since there is a 4 GB limit - only if the compiler's "long" type is 32 bits. If the compiler's "long" - type is 64 bits, then the limit is 16 exabytes. + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. 33. Does zlib have any security vulnerabilities? - The only one that we are aware of is potentially in gzprintf(). If zlib - is compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of a 4K string space, other than the caller of - gzprintf() assuring that the output will not exceed 4K. On the other - hand, if zlib is compiled to use snprintf() or vsnprintf(), which should - normally be the case, then there is no vulnerability. The ./configure - script will display warnings if an insecure variation of sprintf() will - be used by gzprintf(). Also the zlibCompileFlags() function will return - information on what variant of sprintf() is used by gzprintf(). + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). If you don't have snprintf() or vsnprintf() and would like one, you can find a portable implementation here: http://www.ijs.si/software/snprintf/ - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability. + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. 34. Is there a Java version of zlib? Probably what you want is to use zlib in Java. zlib is already included as part of the Java SDK in the java.util.zip package. If you really want a version of zlib written in the Java language, look on the zlib home - page for links: http://www.zlib.org/ + page for links: http://zlib.net/ . 35. I get this or that compiler or source-code scanner warning when I crank it up to maximally-pedantic. Can't you guys write proper code? Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly. So now, we simply make sure that the code always - works. + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. 36. Valgrind (or some similar memory access checker) says that deflate is performing a conditional jump that depends on an uninitialized value. Isn't that a bug? - No. That is intentional for performance reasons, and the output of - deflate is not affected. This only started showing up recently since - zlib 1.2.x uses malloc() by default for allocations, whereas earlier - versions used calloc(), which zeros out the allocated memory. + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. 37. Will zlib read the (insert any ancient or arcane format here) compressed data format? @@ -305,20 +311,21 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 38. How can I encrypt/decrypt zip files with zlib? - zlib doesn't support encryption. The original PKZIP encryption is very weak - and can be broken with freely available programs. To get strong encryption, - use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. - For PKZIP compatible "encryption", look at http://www.info-zip.org/ + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://www.info-zip.org/ 39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion - with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 correctly points to the zlib specification in RFC 1950 for the "deflate" transfer encoding, there have been reports of servers and browsers that incorrectly produce or expect raw deflate data per the deflate - specficiation in RFC 1951, most notably Microsoft. So even though the + specficiation in RFC 1951, most notably Microsoft. So even though the "deflate" transfer encoding using the zlib format would be the more efficient approach (and in fact exactly what the zlib format was designed for), using the "gzip" transfer encoding is probably more reliable due to @@ -328,12 +335,32 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 40. Does zlib support the new "Deflate64" format introduced by PKWare? - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. - In any case, the compression improvements are so modest compared to other - more modern approaches, that it's not worth the effort to implement. + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. -41. Can you please sign these lengthy legal documents and fax them back to us +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us so that we can use your software in our product? No. Go away. Shoo. diff --git a/lib/3rdparty/zlib/INDEX b/lib/3rdparty/zlib/INDEX index 0587e5902bd..f6c51ca1759 100644 --- a/lib/3rdparty/zlib/INDEX +++ b/lib/3rdparty/zlib/INDEX @@ -1,23 +1,32 @@ +CMakeLists.txt cmake build file ChangeLog history of changes FAQ Frequently Asked Questions about zlib INDEX this file -Makefile makefile for Unix (generated by configure) -Makefile.in makefile for Unix (template for configure) +Makefile dummy Makefile that tells you to ./configure +Makefile.in template for Unix Makefile README guess what -algorithm.txt description of the (de)compression algorithm configure configure script for Unix -zconf.in.h template for zconf.h (used by configure) +make_vms.com makefile for VMS +treebuild.xml XML description of source file dependencies +zconf.h.cmakein zconf.h template for cmake +zconf.h.in zconf.h template for configure +zlib.3 Man page for zlib +zlib.3.pdf Man page in PDF format +zlib.map Linux symbol information +zlib.pc.in Template for pkg-config descriptor +zlib2ansi perl script to convert source files for C++ compilation amiga/ makefiles for Amiga SAS C -as400/ makefiles for IBM AS/400 +doc/ documentation for formats and algorithms msdos/ makefiles for MSDOS +nintendods/ makefile for Nintendo DS old/ makefiles for various architectures and zlib documentation files that have not yet been updated for zlib 1.2.x -projects/ projects for various Integrated Development Environments qnx/ makefiles for QNX +watcom/ makefiles for OpenWatcom win32/ makefiles for Windows - zlib public header files (must be kept): + zlib public header files (required for library use): zconf.h zlib.h @@ -28,7 +37,11 @@ crc32.c crc32.h deflate.c deflate.h -gzio.c +gzclose.c +gzguts.h +gzlib.c +gzread.c +gzwrite.c infback.c inffast.c inffast.h @@ -46,6 +59,7 @@ zutil.h source files for sample programs: example.c minigzip.c +See examples/README.examples for more unsupported contribution by third parties See contrib/README.contrib diff --git a/lib/3rdparty/zlib/Makefile.host b/lib/3rdparty/zlib/Makefile.host deleted file mode 100755 index 6a2a9b38267..00000000000 --- a/lib/3rdparty/zlib/Makefile.host +++ /dev/null @@ -1,46 +0,0 @@ -# $Id$ -PATH_TO_TOP = ../.. - -TARGET = zlib.host.a - -CFLAGS = \ - -MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -OBJECTS = \ - adler32.o \ - compress.o \ - crc32.o \ - gzio.o \ - uncompr.o \ - deflate.o \ - trees.o \ - zutil.o \ - inflate.o \ - infblock.o \ - inftrees.o \ - infcodes.o \ - infutil.o \ - inffast.o - -OBJECTS := $(OBJECTS:%=hostobjs/%) - -all: hostobjs $(TARGET) - -hostobjs: - - $(RMKDIR) hostobjs - -hostobjs/%.o: %.c - $(HOST_CC) $(CFLAGS) -c $< -o $@ - -$(TARGET): $(OBJECTS) - $(HOST_AR) -r $(TARGET) $^ - -clean: - - $(RM) hostobjs/* - - $(RM) $(TARGET) - - $(RMDIR) hostobjs - -.phony: clean - -include $(PATH_TO_TOP)/rules.mak diff --git a/lib/3rdparty/zlib/Makefile.in b/lib/3rdparty/zlib/Makefile.in index 2fd6e45c48d..5b15bd00d73 100644 --- a/lib/3rdparty/zlib/Makefile.in +++ b/lib/3rdparty/zlib/Makefile.in @@ -1,11 +1,11 @@ # Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. +# Copyright (C) 1995-2010 Jean-loup Gailly. # For conditions of distribution and use, see copyright notice in zlib.h # To compile and test, type: # ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static # To use the asm code, type: # cp contrib/asm?86/match.S ./match.S @@ -24,17 +24,22 @@ CFLAGS=-O #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ # -Wstrict-prototypes -Wmissing-prototypes -LDFLAGS=libz.a +SFLAGS=-O +LDFLAGS= +TEST_LDFLAGS=-L. libz.a LDSHARED=$(CC) CPP=$(CC) -E -LIBS=libz.a +STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 +SHAREDLIBV=libz.so.1.2.5 SHAREDLIBM=libz.so.1 +LIBS=$(STATICLIB) $(SHAREDLIBV) AR=ar rc RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC=-lc TAR=tar SHELL=/bin/sh EXE= @@ -42,33 +47,68 @@ EXE= prefix = /usr/local exec_prefix = ${prefix} libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} includedir = ${prefix}/include mandir = ${prefix}/share/man man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o +OBJC = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o +PIC_OBJC = adler32.lo compress.lo crc32.lo deflate.lo gzclose.lo gzlib.lo gzread.lo \ + gzwrite.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo uncompr.lo zutil.lo + +# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo OBJA = -# to use the asm code: make OBJA=match.o +PIC_OBJA = -TEST_OBJS = example.o minigzip.o +OBJS = $(OBJC) $(OBJA) -all: example$(EXE) minigzip$(EXE) +PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) + +all: static shared + +static: example$(EXE) minigzip$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +all64: example64$(EXE) minigzip64$(EXE) check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ + +test: all teststatic testshared + +teststatic: static + @if echo hello world | ./minigzip | ./minigzip -d && ./example; then \ echo ' *** zlib test OK ***'; \ else \ - echo ' *** zlib test FAILED ***'; \ + echo ' *** zlib test FAILED ***'; false; \ fi + -@rm -f foo.gz -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) +testshared: shared + @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ + if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +test64: all64 + @if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64; then \ + echo ' *** zlib 64-bit test OK ***'; \ + else \ + echo ' *** zlib 64-bit test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 match.o: match.S @@ -77,58 +117,116 @@ match.o: match.S mv _match.o match.o rm -f _match.s -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) +match.lo: match.S + $(CPP) match.S > _match.s + $(CC) -c -fPIC _match.s + mv _match.o match.lo + rm -f _match.s + +example64.o: example.c zlib.h zconf.h + $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ example.c + +minigzip64.o: minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ minigzip.c + +.SUFFIXES: .lo + +.c.lo: + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $< + -@mv objs/$*.o $@ + +$(SHAREDLIBV): $(PIC_OBJS) + $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) rm -f $(SHAREDLIB) $(SHAREDLIBM) ln -s $@ $(SHAREDLIB) ln -s $@ $(SHAREDLIBM) + -@rmdir objs -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) +example$(EXE): example.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) +minigzip$(EXE): minigzip.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ +examplesh$(EXE): example.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) + +minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) + +example64$(EXE): example64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + +minigzip64$(EXE): minigzip64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) + +install-libs: $(LIBS) + -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + cp $(STATICLIB) $(DESTDIR)$(libdir) + cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir) + cd $(DESTDIR)$(libdir); chmod u=rw,go=r $(STATICLIB) + -@(cd $(DESTDIR)$(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + -@cd $(DESTDIR)$(sharedlibdir); if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ + chmod 755 $(SHAREDLIBV); \ rm -f $(SHAREDLIB) $(SHAREDLIBM); \ ln -s $(SHAREDLIBV) $(SHAREDLIB); \ ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ + ($(LDCONFIG) || true) >/dev/null 2>&1; \ fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 + cp zlib.3 $(DESTDIR)$(man3dir) + chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + cp zlib.pc $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc # The ranlib in install is needed on NeXTSTEP which checks file times # ldconfig is for Linux +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + cp zlib.h zconf.h $(DESTDIR)$(includedir) + chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ + cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h + cd $(DESTDIR)$(libdir); rm -f libz.a; \ + if test "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ fi - cd $(man3dir); rm -f zlib.3 + cd $(DESTDIR)$(man3dir); rm -f zlib.3 + cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc + +docs: zlib.3.pdf + +zlib.3.pdf: zlib.3 + groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf + +zconf.h.in: zconf.h.cmakein + sed "/^#cmakedefine/D" < zconf.h.cmakein > zconf.h.in + touch -r zconf.h.cmakein zconf.h.in + +zconf: zconf.h.in + cp -p zconf.h.in zconf.h mostlyclean: clean clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ + example64$(EXE) minigzip64$(EXE) \ libz.* foo.gz so_locations \ _match.s maketree contrib/infback9/*.o + rm -rf objs maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store +distclean: clean zconf docs + rm -f Makefile zlib.pc + -@rm -f .DS_Store + -@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile + -@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile + -@touch -r Makefile.in Makefile tags: etags *.[ch] @@ -138,17 +236,22 @@ depend: # DO NOT DELETE THIS LINE -- make depend depends on it. -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h +adler32.o zutil.o: zutil.h zlib.h zconf.h +gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h +compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h crc32.h deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h +infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h + +adler32.lo zutil.lo: zutil.h zlib.h zconf.h +gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h +compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h +crc32.lo: zutil.h zlib.h zconf.h crc32.h +deflate.lo: deflate.h zutil.h zlib.h zconf.h +infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h +inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.lo: zutil.h zlib.h zconf.h inftrees.h +trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h diff --git a/lib/3rdparty/zlib/README b/lib/3rdparty/zlib/README index 758cc50020d..d4219bf889f 100644 --- a/lib/3rdparty/zlib/README +++ b/lib/3rdparty/zlib/README @@ -1,56 +1,52 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.3 is a general purpose data compression library. All the code is +zlib 1.2.5 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). These documents are also available in other -formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +and rfc1952.txt (gzip format). All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The +is working correctly. Another example is given in the file minigzip.c. The compression library itself is composed of all source files except example.c and minigzip.c. To compile all files and run the test program, follow the instructions given at -the top of Makefile. In short "make test; make install" should work for most -machines. For Unix: "./configure; make test; make install". For MSDOS, use one -of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use one +of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, -please check this site to verify that you have the latest version of zlib; -otherwise get the latest version and check whether the problem still exists or -not. + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. -PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking -for help. +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available in -http://dogma.net/markn/articles/zlibtool/zlibtool.htm +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.3 are documented in the file ChangeLog. +The changes made in version 1.2.5 are documented in the file ChangeLog. -Unsupported third party contributions are provided in directory "contrib". +Unsupported third party contributions are provided in directory contrib/ . -A Java implementation of zlib is available in the Java Development Kit -http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html -See the zlib home page http://www.zlib.org for details. +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . -A Perl interface to zlib written by Paul Marquess is in the -CPAN (Comprehensive Perl Archive Network) sites -http://www.cpan.org/modules/by-module/Compress/ +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html +http://www.python.org/doc/lib/module-zlib.html . -A zlib binding for TCL written by Andreas Kupries is -availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html +zlib is built into tcl: http://wiki.tcl.tk/4610 . An experimental package to read and write files in .zip format, written on top of zlib by Gilles Vollant , is available in the @@ -74,25 +70,21 @@ Notes for some targets: - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with other compilers. Use "make test" to check your compiler. -- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. +- gzdopen is not supported on RISCOS or BEOS. - For PalmOs, see http://palmzlib.sourceforge.net/ -- When building a shared, i.e. dynamic library on Mac OS X, the library must be - installed before testing (do "make install" before "make test"), since the - library location is specified in the library. - Acknowledgments: - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. Copyright notice: - (C) 1995-2004 Jean-loup Gailly and Mark Adler + (C) 1995-2010 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -113,13 +105,11 @@ Copyright notice: Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. Please -read the FAQ for more information on the distribution of modified source -versions. +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/lib/3rdparty/zlib/adler32.c b/lib/3rdparty/zlib/adler32.c index 007ba26277c..65ad6a5adc4 100644 --- a/lib/3rdparty/zlib/adler32.c +++ b/lib/3rdparty/zlib/adler32.c @@ -1,12 +1,15 @@ /* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2004 Mark Adler + * Copyright (C) 1995-2007 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ -#define ZLIB_INTERNAL -#include "zlib.h" +#include "zutil.h" + +#define local static + +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 @@ -125,10 +128,10 @@ uLong ZEXPORT adler32(adler, buf, len) } /* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) +local uLong adler32_combine_(adler1, adler2, len2) uLong adler1; uLong adler2; - z_off_t len2; + z_off64_t len2; { unsigned long sum1; unsigned long sum2; @@ -141,9 +144,26 @@ uLong ZEXPORT adler32_combine(adler1, adler2, len2) MOD(sum2); sum1 += (adler2 & 0xffff) + BASE - 1; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 > BASE) sum1 -= BASE; - if (sum1 > BASE) sum1 -= BASE; - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 > BASE) sum2 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/lib/3rdparty/zlib/algorithm.txt b/lib/3rdparty/zlib/algorithm.txt index b022dde312a..34960bddacc 100644 --- a/lib/3rdparty/zlib/algorithm.txt +++ b/lib/3rdparty/zlib/algorithm.txt @@ -121,7 +121,7 @@ At least for deflate's output that generates new trees every several 10's of kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code would take too long if you're only decoding several thousand symbols. At the other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend two much time +that's essentially a Huffman tree. But then you spend too much time traversing the tree while decoding, even for short symbols. So the number of bits for the first lookup table is a trade of the time to diff --git a/lib/3rdparty/zlib/compress.c b/lib/3rdparty/zlib/compress.c index df04f0148e6..ea4dfbe9d7b 100644 --- a/lib/3rdparty/zlib/compress.c +++ b/lib/3rdparty/zlib/compress.c @@ -1,5 +1,5 @@ /* compress.c -- compress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. + * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -75,5 +75,6 @@ int ZEXPORT compress (dest, destLen, source, sourceLen) uLong ZEXPORT compressBound (sourceLen) uLong sourceLen; { - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; } diff --git a/lib/3rdparty/zlib/configure b/lib/3rdparty/zlib/configure index d7ffdc3458d..bd9edd26cdd 100644 --- a/lib/3rdparty/zlib/configure +++ b/lib/3rdparty/zlib/configure @@ -1,37 +1,61 @@ #!/bin/sh -# configure script for zlib. This script is needed only if -# you wish to build a shared library and your system supports them, -# of if you need special compiler, flags or install directory. -# Otherwise, you can just use directly "make test; make install" +# configure script for zlib. # -# To create a shared library, use "configure --shared"; by default a static -# library is created. If the primitive shared library support provided here -# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static # # To impose specific compiler or flags or install directory, use for example: # prefix=$HOME CC=cc CFLAGS="-O4" ./configure # or for csh/tcsh users: # (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) -# LDSHARED is the command to be used to create a shared library # Incorrect settings of CC or CFLAGS may prevent creating a shared library. # If you have problems, try without defining CC and CFLAGS before reporting # an error. -LIBS=libz.a -LDFLAGS="-L. ${LIBS}" +if [ -n "${CHOST}" ]; then + uname="$(echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')" + CROSS_PREFIX="${CHOST}-" +fi + +STATICLIB=libz.a +LDFLAGS="${LDFLAGS} -L. ${STATICLIB}" VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h` VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` -AR=${AR-"ar rc"} -RANLIB=${RANLIB-"ranlib"} +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} +fi +AR_RC="${AR} rc" +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} +else + RANLIB=${RANLIB-"ranlib"} +fi +if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then + NM=${NM-"${CROSS_PREFIX}nm"} + test -n "${CROSS_PREFIX}" && echo Using ${NM} +else + NM=${NM-"nm"} +fi +LDCONFIG=${LDCONFIG-"ldconfig"} +LDSHAREDLIBC="${LDSHAREDLIBC--lc}" prefix=${prefix-/usr/local} exec_prefix=${exec_prefix-'${prefix}'} libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} includedir=${includedir-'${prefix}/include'} mandir=${mandir-'${prefix}/share/man'} shared_ext='.so' -shared=0 +shared=1 +zprefix=0 +build64=0 gcc=0 old_cc="$CC" old_cflags="$CFLAGS" @@ -39,21 +63,29 @@ old_cflags="$CFLAGS" while test $# -ge 1 do case "$1" in - -h* | --h*) + -h* | --help) echo 'usage:' - echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' - echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' - exit 0;; - -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; - -p* | --p*) prefix="$2"; shift; shift;; - -e* | --e*) exec_prefix="$2"; shift; shift;; - -l* | --l*) libdir="$2"; shift; shift;; - -i* | --i*) includedir="$2"; shift; shift;; - -s* | --s*) shared=1; shift;; - *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;; + echo ' configure [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' + echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' + echo ' [--includedir=INCLUDEDIR]' + exit 0 ;; + -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; + --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; + -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + -z* | --zprefix) zprefix=1; shift ;; + -6* | --64) build64=1; shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir"; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir"; shift ;; + *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1 ;; esac done @@ -63,46 +95,68 @@ extern int getchar(); int hello() {return getchar();} EOF -test -z "$CC" && echo Checking for gcc... -cc=${CC-gcc} +test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... +cc=${CC-${CROSS_PREFIX}gcc} cflags=${CFLAGS-"-O3"} # to force the asm version use: CFLAGS="-O3 -DASMV" ./configure case "$cc" in - *gcc*) gcc=1;; + *gcc*) gcc=1 ;; esac if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then CC="$cc" - SFLAGS=${CFLAGS-"-fPIC -O3"} - CFLAGS="$cflags" - case `(uname -s || echo unknown) 2>/dev/null` in - Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};; - CYGWIN* | Cygwin* | cygwin* | OS/2* ) - EXE='.exe';; + SFLAGS="${CFLAGS--O3} -fPIC" + CFLAGS="${CFLAGS--O3}" + if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + fi + if test "${ZLIBGCCWARN}" = "YES"; then + CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + fi + if test -z "$uname"; then + uname=`(uname -s || echo unknown) 2>/dev/null` + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | *BSD | DragonFly) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;; + CYGWIN* | Cygwin* | cygwin* | OS/2*) + EXE='.exe' ;; + MINGW*|mingw*) +# temporary bypass + rm -f $test.[co] $test $test$shared_ext + echo "Please use win32/Makefile.gcc instead." + exit 1 + LDSHARED=${LDSHARED-"$cc -shared"} + LDSHAREDLIBC="" + EXE='.exe' ;; QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 # (alain.bonnefoy@icbt.com) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};; + LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; HP-UX*) LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} case `(uname -m || echo unknown) 2>/dev/null` in ia64) shared_ext='.so' - SHAREDLIB='libz.so';; + SHAREDLIB='libz.so' ;; *) shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; + SHAREDLIB='libz.sl' ;; + esac ;; Darwin*) shared_ext='.dylib' SHAREDLIB=libz$shared_ext SHAREDLIBV=libz.$VER$shared_ext SHAREDLIBM=libz.$VER1$shared_ext - LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};; - *) LDSHARED=${LDSHARED-"$cc -shared"};; + LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} ;; + *) LDSHARED=${LDSHARED-"$cc -shared"} ;; esac else # find system name and corresponding cc options CC=${CC-cc} - case `(uname -sr || echo unknown) 2>/dev/null` in + gcc=0 + if test -z "$uname"; then + uname=`(uname -sr || echo unknown) 2>/dev/null` + fi + case "$uname" in HP-UX*) SFLAGS=${CFLAGS-"-O +z"} CFLAGS=${CFLAGS-"-O"} # LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} @@ -110,57 +164,64 @@ else case `(uname -m || echo unknown) 2>/dev/null` in ia64) shared_ext='.so' - SHAREDLIB='libz.so';; + SHAREDLIB='libz.so' ;; *) shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; + SHAREDLIB='libz.sl' ;; + esac ;; IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} CFLAGS=${CFLAGS-"-ansi -O2"} - LDSHARED=${LDSHARED-"cc -shared"};; + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; + LDFLAGS="${LDFLAGS} -Wl,-rpath,." + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;; OSF1*) SFLAGS=${CFLAGS-"-O -std1"} CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared"};; + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; QNX*) SFLAGS=${CFLAGS-"-4 -O"} CFLAGS=${CFLAGS-"-4 -O"} LDSHARED=${LDSHARED-"cc"} RANLIB=${RANLIB-"true"} - AR="cc -A";; + AR_RC="cc -A" ;; SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} CFLAGS=${CFLAGS-"-O3"} - LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; - SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} - CFLAGS=${CFLAGS-"-fast -xcg89"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;; + SunOS\ 5*) LDSHARED=${LDSHARED-"cc -G"} + case `(uname -m || echo unknown) 2>/dev/null` in + i86*) + SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."} + CFLAGS=${CFLAGS-"-xpentium -fast"} ;; + *) + SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."} + CFLAGS=${CFLAGS-"-fast -xcg92"} ;; + esac ;; SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} CFLAGS=${CFLAGS-"-O2"} - LDSHARED=${LDSHARED-"ld"};; - SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} - CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"} - LDSHARED=${LDSHARED-"cc -xarch=v9b"};; + LDSHARED=${LDSHARED-"ld"} ;; + SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} + CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"} + LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;; UNIX_System_V\ 4.2.0) SFLAGS=${CFLAGS-"-KPIC -O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -G"} ;; UNIX_SV\ 4.2MP) SFLAGS=${CFLAGS-"-Kconform_pic -O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -G"} ;; OpenUNIX\ 5) SFLAGS=${CFLAGS-"-KPIC -O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; + LDSHARED=${LDSHARED-"cc -G"} ;; AIX*) # Courtesy of dbakker@arrayasolutions.com SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - LDSHARED=${LDSHARED-"xlc -G"};; - # send working options for other systems to support@gzip.org + LDSHARED=${LDSHARED-"xlc -G"} ;; + # send working options for other systems to zlib@gzip.org *) SFLAGS=${CFLAGS-"-O"} CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -shared"};; + LDSHARED=${LDSHARED-"cc -shared"} ;; esac fi @@ -171,38 +232,83 @@ SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} if test $shared -eq 1; then echo Checking for shared library support... # we must test in two steps (cc then ld), required at least on SunOS 4.x - if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && - test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then - CFLAGS="$SFLAGS" - LIBS="$SHAREDLIBV" + if test "`($CC -w -c $SFLAGS $test.c) 2>&1`" = "" && + test "`($LDSHARED $SFLAGS -o $test$shared_ext $test.o) 2>&1`" = ""; then echo Building shared library $SHAREDLIBV with $CC. elif test -z "$old_cc" -a -z "$old_cflags"; then echo No shared library support. shared=0; else + echo Tested $CC -w -c $SFLAGS $test.c + $CC -w -c $SFLAGS $test.c + echo Tested $LDSHARED $SFLAGS -o $test$shared_ext $test.o + $LDSHARED $SFLAGS -o $test$shared_ext $test.o echo 'No shared library support; try without defining CC and CFLAGS' shared=0; fi fi if test $shared -eq 0; then LDSHARED="$CC" - echo Building static library $LIBS version $VER with $CC. + ALL="static" + TEST="all teststatic" + SHAREDLIB="" + SHAREDLIBV="" + SHAREDLIBM="" + echo Building static library $STATICLIB version $VER with $CC. else - LDFLAGS="-L. ${SHAREDLIBV}" + ALL="static shared" + TEST="all teststatic testshared" fi +cat > $test.c < +off64_t dummy = 0; +EOF +if test "`($CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c) 2>&1`" = ""; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + ALL="${ALL} all64" + TEST="${TEST} test64" + echo "Checking for off64_t... Yes." + echo "Checking for fseeko... Yes." +else + echo "Checking for off64_t... No." + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then + echo "Checking for fseeko... Yes." + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." + fi +fi + +cp -p zconf.h.in zconf.h + cat > $test.c < int main() { return 0; } EOF if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h + sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h echo "Checking for unistd.h... Yes." else - cp -p zconf.in.h zconf.h echo "Checking for unistd.h... No." fi +if test $zprefix -eq 1; then + sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Using z_ prefix on all symbols." +fi + cat > $test.c < #include @@ -219,13 +325,13 @@ int main() EOF if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()" + echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." cat > $test.c < #include -int mytest(char *fmt, ...) +int mytest(const char *fmt, ...) { char buf[20]; va_list ap; @@ -249,7 +355,7 @@ EOF #include #include -int mytest(char *fmt, ...) +int mytest(const char *fmt, ...) { int n; char buf[20]; @@ -271,6 +377,7 @@ EOF echo "Checking for return value of vsnprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_vsnprintf_void" + SFLAGS="$SFLAGS -DHAS_vsnprintf_void" echo "Checking for return value of vsnprintf()... No." echo " WARNING: apparently vsnprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -278,6 +385,7 @@ EOF fi else CFLAGS="$CFLAGS -DNO_vsnprintf" + SFLAGS="$SFLAGS -DNO_vsnprintf" echo "Checking for vsnprintf() in stdio.h... No." echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" echo " can build but will be open to possible buffer-overflow security" @@ -287,7 +395,7 @@ EOF #include #include -int mytest(char *fmt, ...) +int mytest(const char *fmt, ...) { int n; char buf[20]; @@ -309,6 +417,7 @@ EOF echo "Checking for return value of vsprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_vsprintf_void" + SFLAGS="$SFLAGS -DHAS_vsprintf_void" echo "Checking for return value of vsprintf()... No." echo " WARNING: apparently vsprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -316,7 +425,7 @@ EOF fi fi else - echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()" + echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." cat >$test.c < @@ -358,6 +467,7 @@ EOF echo "Checking for return value of snprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_snprintf_void" + SFLAGS="$SFLAGS -DHAS_snprintf_void" echo "Checking for return value of snprintf()... No." echo " WARNING: apparently snprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -365,6 +475,7 @@ EOF fi else CFLAGS="$CFLAGS -DNO_snprintf" + SFLAGS="$SFLAGS -DNO_snprintf" echo "Checking for snprintf() in stdio.h... No." echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" echo " can build but will be open to possible buffer-overflow security" @@ -390,6 +501,7 @@ EOF echo "Checking for return value of sprintf()... Yes." else CFLAGS="$CFLAGS -DHAS_sprintf_void" + SFLAGS="$SFLAGS -DHAS_sprintf_void" echo "Checking for return value of sprintf()... No." echo " WARNING: apparently sprintf() does not return a value. zlib" echo " can build but will be open to possible string-format security" @@ -398,41 +510,37 @@ EOF fi fi -cat >$test.c < -int main() { return 0; } -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for errno.h... Yes." -else - echo "Checking for errno.h... No." - CFLAGS="$CFLAGS -DNO_ERRNO_H" -fi - -cat > $test.c < -#include -#include -caddr_t hello() { - return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); +if test "$gcc" -eq 1; then + cat > $test.c <= 33) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif +int ZLIB_INTERNAL foo; +int main() +{ + return 0; } EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - CFLAGS="$CFLAGS -DUSE_MMAP" - echo Checking for mmap support... Yes. -else - echo Checking for mmap support... No. + if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + echo "Checking for attribute(visibility) support... Yes." + else + CFLAGS="$CFLAGS -DNO_VIZ" + SFLAGS="$SFLAGS -DNO_VIZ" + echo "Checking for attribute(visibility) support... No." + fi fi CPP=${CPP-"$CC -E"} case $CFLAGS in *ASMV*) - if test "`nm $test.o | grep _hello`" = ""; then + if test "`$NM $test.o | grep _hello`" = ""; then CPP="$CPP -DNO_UNDERLINE" echo Checking for underline in external names... No. else echo Checking for underline in external names... Yes. - fi;; + fi ;; esac rm -f $test.[co] $test $test$shared_ext @@ -441,19 +549,48 @@ rm -f $test.[co] $test $test$shared_ext sed < Makefile.in " /^CC *=/s#=.*#=$CC# /^CFLAGS *=/s#=.*#=$CFLAGS# -/^CPP *=/s#=.*#=$CPP# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# /^LDSHARED *=/s#=.*#=$LDSHARED# -/^LIBS *=/s#=.*#=$LIBS# +/^CPP *=/s#=.*#=$CPP# +/^STATICLIB *=/s#=.*#=$STATICLIB# /^SHAREDLIB *=/s#=.*#=$SHAREDLIB# /^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# /^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^AR *=/s#=.*#=$AR# +/^AR *=/s#=.*#=$AR_RC# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^all: */s#:.*#: $ALL# +/^test: */s#:.*#: $TEST# +" > Makefile + +sed < zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^CPP *=/s#=.*#=$CPP# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR_RC# /^RANLIB *=/s#=.*#=$RANLIB# /^EXE *=/s#=.*#=$EXE# /^prefix *=/s#=.*#=$prefix# /^exec_prefix *=/s#=.*#=$exec_prefix# /^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# /^includedir *=/s#=.*#=$includedir# /^mandir *=/s#=.*#=$mandir# /^LDFLAGS *=/s#=.*#=$LDFLAGS# -" > Makefile +" | sed -e " +s/\@VERSION\@/$VER/g; +" > zlib.pc diff --git a/lib/3rdparty/zlib/crc32.c b/lib/3rdparty/zlib/crc32.c index f658a9ef55e..91be372d224 100644 --- a/lib/3rdparty/zlib/crc32.c +++ b/lib/3rdparty/zlib/crc32.c @@ -1,5 +1,5 @@ /* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2006, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster @@ -53,7 +53,7 @@ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); @@ -68,6 +68,8 @@ local unsigned long gf2_matrix_times OF((unsigned long *mat, unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); + #ifdef DYNAMIC_CRC_TABLE @@ -219,7 +221,7 @@ const unsigned long FAR * ZEXPORT get_crc_table() unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; - unsigned len; + uInt len; { if (buf == Z_NULL) return 0UL; @@ -367,22 +369,22 @@ local void gf2_matrix_square(square, mat) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) +local uLong crc32_combine_(crc1, crc2, len2) uLong crc1; uLong crc2; - z_off_t len2; + z_off64_t len2; { int n; unsigned long row; unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - /* degenerate case */ - if (len2 == 0) + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) return crc1; /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ row = 1; for (n = 1; n < GF2_DIM; n++) { odd[n] = row; @@ -421,3 +423,20 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2) crc1 ^= crc2; return crc1; } + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/lib/3rdparty/zlib/deflate.c b/lib/3rdparty/zlib/deflate.c index 29ce1f64a57..5c4022f3d47 100644 --- a/lib/3rdparty/zlib/deflate.c +++ b/lib/3rdparty/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -79,19 +79,18 @@ local block_state deflate_fast OF((deflate_state *s, int flush)); #ifndef FASTEST local block_state deflate_slow OF((deflate_state *s, int flush)); #endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); #ifdef DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, @@ -110,11 +109,6 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be @@ -288,6 +282,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + s->high_water = 0; /* nothing written to s->window yet */ + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); @@ -332,8 +328,8 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) strm->adler = adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); + if (length > s->w_size) { + length = s->w_size; dictionary += dictLength - length; /* use the tail of the dictionary */ } zmemcpy(s->window, dictionary, length); @@ -435,9 +431,10 @@ int ZEXPORT deflateParams(strm, level, strategy) } func = configuration_table[s->level].func; - if (func != configuration_table[level].func && strm->total_in != 0) { + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); + err = deflate(strm, Z_BLOCK); } if (s->level != level) { s->level = level; @@ -481,33 +478,66 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) * resulting from using fixed blocks instead of stored blocks, which deflate * can emit on compressed data for some combinations of the parameters. * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; - uLong destLen; + uLong complen, wraplen; + Bytef *str; - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - /* if can't get parameters, return conservative bound */ + /* if can't get parameters, return conservative bound plus zlib wrapper */ if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } /* if not default parameters, return conservative bound */ - s = strm->state; if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; + return complen + wraplen; /* default settings: return tight bound for that case */ - return compressBound(sourceLen); + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; } /* ========================================================================= @@ -557,7 +587,7 @@ int ZEXPORT deflate (strm, flush) deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { + flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; @@ -581,7 +611,7 @@ int ZEXPORT deflate (strm, flush) put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); - if (s->gzhead == NULL) { + if (s->gzhead == Z_NULL) { put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); @@ -608,7 +638,7 @@ int ZEXPORT deflate (strm, flush) (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != NULL) { + if (s->gzhead->extra != Z_NULL) { put_byte(s, s->gzhead->extra_len & 0xff); put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } @@ -650,7 +680,7 @@ int ZEXPORT deflate (strm, flush) } #ifdef GZIP if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != NULL) { + if (s->gzhead->extra != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { @@ -678,7 +708,7 @@ int ZEXPORT deflate (strm, flush) s->status = NAME_STATE; } if (s->status == NAME_STATE) { - if (s->gzhead->name != NULL) { + if (s->gzhead->name != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; @@ -709,7 +739,7 @@ int ZEXPORT deflate (strm, flush) s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != NULL) { + if (s->gzhead->comment != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; @@ -787,7 +817,9 @@ int ZEXPORT deflate (strm, flush) (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; - bstate = (*(configuration_table[s->level].func))(s, flush); + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; @@ -808,13 +840,17 @@ int ZEXPORT deflate (strm, flush) if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + } } } flush_pending(strm); @@ -1167,12 +1203,13 @@ local uInt longest_match(s, cur_match) return s->lookahead; } #endif /* ASMV */ -#endif /* FASTEST */ + +#else /* FASTEST */ /* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only + * Optimized version for FASTEST only */ -local uInt longest_match_fast(s, cur_match) +local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { @@ -1225,6 +1262,8 @@ local uInt longest_match_fast(s, cur_match) return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } +#endif /* FASTEST */ + #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. @@ -1303,7 +1342,6 @@ local void fill_window(s) later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ - /* %%% avoid this when Z_RLE */ n = s->hash_size; p = &s->head[n]; do { @@ -1355,27 +1393,61 @@ local void fill_window(s) */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ +#define FLUSH_BLOCK_ONLY(s, last) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ + (last)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } /* =========================================================================== @@ -1449,7 +1521,7 @@ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { - IPos hash_head = NIL; /* head of the hash chain */ + IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { @@ -1469,6 +1541,7 @@ local block_state deflate_fast(s, flush) /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ + hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } @@ -1481,19 +1554,8 @@ local block_state deflate_fast(s, flush) * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ -#ifdef FASTEST - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); @@ -1555,7 +1617,7 @@ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { - IPos hash_head = NIL; /* head of hash chain */ + IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ @@ -1576,6 +1638,7 @@ local block_state deflate_slow(s, flush) /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ + hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } @@ -1591,12 +1654,8 @@ local block_state deflate_slow(s, flush) * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 @@ -1674,7 +1733,6 @@ local block_state deflate_slow(s, flush) } #endif /* FASTEST */ -#if 0 /* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of @@ -1684,11 +1742,9 @@ local block_state deflate_rle(s, flush) deflate_state *s; int flush; { - int bflush; /* set if current block must be flushed */ - uInt run; /* length of run */ - uInt max; /* maximum length of run */ - uInt prev; /* byte at distance one to match */ - Bytef *scan; /* scan for end of run */ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ for (;;) { /* Make sure that we always have enough lookahead, except @@ -1704,23 +1760,33 @@ local block_state deflate_rle(s, flush) } /* See how many times the previous byte repeats */ - run = 0; - if (s->strstart > 0) { /* if there is a previous byte, that is */ - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { scan = s->window + s->strstart - 1; - prev = *scan++; - do { - if (*scan++ != prev) - break; - } while (++run < max); + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (run >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, run); - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); - s->lookahead -= run; - s->strstart += run; + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); @@ -1733,4 +1799,36 @@ local block_state deflate_rle(s, flush) FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } -#endif + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/lib/3rdparty/zlib/deflate.h b/lib/3rdparty/zlib/deflate.h index 05a5ab3a2c1..e970d73baad 100644 --- a/lib/3rdparty/zlib/deflate.h +++ b/lib/3rdparty/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2004 Jean-loup Gailly + * Copyright (C) 1995-2010 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -260,6 +260,13 @@ typedef struct internal_state { * are always zero. */ + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + } FAR deflate_state; /* Output a byte on the stream. @@ -278,14 +285,18 @@ typedef struct internal_state { * distances are limited to MAX_DIST instead of WSIZE. */ +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) diff --git a/lib/3rdparty/zlib/example.c b/lib/3rdparty/zlib/example.c index 6c8a0ee7633..604736f15f6 100644 --- a/lib/3rdparty/zlib/example.c +++ b/lib/3rdparty/zlib/example.c @@ -1,12 +1,12 @@ /* example.c -- usage example of the zlib compression library - * Copyright (C) 1995-2004 Jean-loup Gailly. + * Copyright (C) 1995-2006 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ -#include #include "zlib.h" +#include #ifdef STDC # include diff --git a/lib/3rdparty/zlib/gzclose.c b/lib/3rdparty/zlib/gzclose.c new file mode 100644 index 00000000000..caeb99a3177 --- /dev/null +++ b/lib/3rdparty/zlib/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/lib/3rdparty/zlib/gzguts.h b/lib/3rdparty/zlib/gzguts.h new file mode 100644 index 00000000000..055455af860 --- /dev/null +++ b/lib/3rdparty/zlib/gzguts.h @@ -0,0 +1,132 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifdef _MSC_VER +# include +# define vsnprintf _vsnprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifdef STDC +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default i/o buffer size -- double this for output when reading */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + z_off64_t pos; /* current position in uncompressed data */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + unsigned char *next; /* next output data to deliver or write */ + /* just for reading */ + unsigned have; /* amount of output data unused at next */ + int eof; /* true if end of input file reached */ + z_off64_t start; /* where the gzip data started, for rewinding */ + z_off64_t raw; /* where the raw data started, for seeking */ + int how; /* 0: get header, 1: copy, 2: decompress */ + int direct; /* true if last read direct, false if gzip */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/lib/3rdparty/zlib/gzio.c b/lib/3rdparty/zlib/gzio.c deleted file mode 100644 index 7e90f4928fc..00000000000 --- a/lib/3rdparty/zlib/gzio.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* gzio.c -- IO on .gz files - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. - */ - -/* @(#) $Id$ */ - -#include - -#include "zutil.h" - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef Z_BUFSIZE -# ifdef MAXSEG_64K -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ -# else -# define Z_BUFSIZE 16384 -# endif -#endif -#ifndef Z_PRINTF_BUFSIZE -# define Z_PRINTF_BUFSIZE 4096 -#endif - -#ifdef __MVS__ -# pragma map (fdopen , "\174\174FDOPEN") - FILE *fdopen(int, const char *); -#endif - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern void free OF((voidpf ptr)); -#endif - -#define ALLOC(size) malloc(size) -#define TRYFREE(p) {if (p) free(p);} - -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -typedef struct gz_stream { - z_stream stream; - int z_err; /* error code for last stream operation */ - int z_eof; /* set if end of input file */ - FILE *file; /* .gz file */ - Byte *inbuf; /* input buffer */ - Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ - char *msg; /* error message */ - char *path; /* path name for debugging only */ - int transparent; /* 1 if input file is not a .gz file */ - char mode; /* 'w' or 'r' */ - z_off_t start; /* start of compressed data in file (header skipped) */ - z_off_t in; /* bytes into deflate or inflate */ - z_off_t out; /* bytes out of deflate or inflate */ - int back; /* one character push-back */ - int last; /* true if push-back is last character */ -} gz_stream; - - -local gzFile gz_open OF((const char *path, const char *mode, int fd)); -local int do_flush OF((gzFile file, int flush)); -local int get_byte OF((gz_stream *s)); -local void check_header OF((gz_stream *s)); -local int destroy OF((gz_stream *s)); -local void putLong OF((FILE *file, uLong x)); -local uLong getLong OF((gz_stream *s)); - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb"). The file is given either by file descriptor - or path name (if fd == -1). - gz_open returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). -*/ -local gzFile gz_open (path, mode, fd) - const char *path; - const char *mode; - int fd; -{ - int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - char *p = (char*)mode; - gz_stream *s; - char fmode[80]; /* copy of mode, without the compression level */ - char *m = fmode; - - if (!path || !mode) return Z_NULL; - - s = (gz_stream *)ALLOC(sizeof(gz_stream)); - if (!s) return Z_NULL; - - s->stream.zalloc = (alloc_func)0; - s->stream.zfree = (free_func)0; - s->stream.opaque = (voidpf)0; - s->stream.next_in = s->inbuf = Z_NULL; - s->stream.next_out = s->outbuf = Z_NULL; - s->stream.avail_in = s->stream.avail_out = 0; - s->file = NULL; - s->z_err = Z_OK; - s->z_eof = 0; - s->in = 0; - s->out = 0; - s->back = EOF; - s->crc = crc32(0L, Z_NULL, 0); - s->msg = NULL; - s->transparent = 0; - - s->path = (char*)ALLOC(strlen(path)+1); - if (s->path == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - strcpy(s->path, path); /* do this early for debugging */ - - s->mode = '\0'; - do { - if (*p == 'r') s->mode = 'r'; - if (*p == 'w' || *p == 'a') s->mode = 'w'; - if (*p >= '0' && *p <= '9') { - level = *p - '0'; - } else if (*p == 'f') { - strategy = Z_FILTERED; - } else if (*p == 'h') { - strategy = Z_HUFFMAN_ONLY; - } else if (*p == 'R') { - strategy = Z_RLE; - } else { - *m++ = *p; /* copy the mode */ - } - } while (*p++ && m != fmode + sizeof(fmode)); - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateInit2(&(s->stream), level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); - /* windowBits is passed < 0 to suppress zlib header */ - - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); -#endif - if (err != Z_OK || s->outbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } else { - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); - - err = inflateInit2(&(s->stream), -MAX_WBITS); - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are - * present after the compressed stream. - */ - if (err != Z_OK || s->inbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } - s->stream.avail_out = Z_BUFSIZE; - - errno = 0; - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); - - if (s->file == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - if (s->mode == 'w') { - /* Write a very simple .gz header: - */ - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); - s->start = 10L; - /* We use 10L instead of ftell(s->file) to because ftell causes an - * fflush on some systems. This version of the library doesn't use - * start anyway in write mode, so this initialization is not - * necessary. - */ - } else { - check_header(s); /* skip the .gz header */ - s->start = ftell(s->file) - s->stream.avail_in; - } - - return (gzFile)s; -} - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. -*/ -gzFile ZEXPORT gzopen (path, mode) - const char *path; - const char *mode; -{ - return gz_open (path, mode, -1); -} - -/* =========================================================================== - Associate a gzFile with the file descriptor fd. fd is not dup'ed here - to mimic the behavio(u)r of fdopen. -*/ -gzFile ZEXPORT gzdopen (fd, mode) - int fd; - const char *mode; -{ - char name[46]; /* allow for up to 128-bit integers */ - - if (fd < 0) return (gzFile)Z_NULL; - sprintf(name, "", fd); /* for debugging */ - - return gz_open (name, mode, fd); -} - -/* =========================================================================== - * Update the compression level and strategy - */ -int ZEXPORT gzsetparams (file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - /* Make room to allow flushing */ - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - } - s->stream.avail_out = Z_BUFSIZE; - } - - return deflateParams (&(s->stream), level, strategy); -} - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ -local int get_byte(s) - gz_stream *s; -{ - if (s->z_eof) return EOF; - if (s->stream.avail_in == 0) { - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) s->z_err = Z_ERRNO; - return EOF; - } - s->stream.next_in = s->inbuf; - } - s->stream.avail_in--; - return *(s->stream.next_in)++; -} - -/* =========================================================================== - Check the gzip header of a gz_stream opened for reading. Set the stream - mode to transparent if the gzip magic header is not present; set s->err - to Z_DATA_ERROR if the magic header is present but the rest of the header - is incorrect. - IN assertion: the stream s has already been created sucessfully; - s->stream.avail_in is zero for the first time, but may be non-zero - for concatenated .gz files. -*/ -local void check_header(s) - gz_stream *s; -{ - int method; /* method byte */ - int flags; /* flags byte */ - uInt len; - int c; - - /* Assure two bytes in the buffer so we can peek ahead -- handle case - where first byte of header is at the end of the buffer after the last - gzip segment */ - len = s->stream.avail_in; - if (len < 2) { - if (len) s->inbuf[0] = s->stream.next_in[0]; - errno = 0; - len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); - if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; - s->stream.avail_in += len; - s->stream.next_in = s->inbuf; - if (s->stream.avail_in < 2) { - s->transparent = s->stream.avail_in; - return; - } - } - - /* Peek ahead to check the gzip magic header */ - if (s->stream.next_in[0] != gz_magic[0] || - s->stream.next_in[1] != gz_magic[1]) { - s->transparent = 1; - return; - } - s->stream.avail_in -= 2; - s->stream.next_in += 2; - - /* Check the rest of the gzip header */ - method = get_byte(s); - flags = get_byte(s); - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { - s->z_err = Z_DATA_ERROR; - return; - } - - /* Discard time, xflags and OS code: */ - for (len = 0; len < 6; len++) (void)get_byte(s); - - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ - len = (uInt)get_byte(s); - len += ((uInt)get_byte(s))<<8; - /* len is garbage if EOF but the loop below will quit anyway */ - while (len-- != 0 && get_byte(s) != EOF) ; - } - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); - } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; -} - - /* =========================================================================== - * Cleanup then free the given gz_stream. Return a zlib error code. - Try freeing in the reverse order of allocations. - */ -local int destroy (s) - gz_stream *s; -{ - int err = Z_OK; - - if (!s) return Z_STREAM_ERROR; - - TRYFREE(s->msg); - - if (s->stream.state != NULL) { - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateEnd(&(s->stream)); -#endif - } else if (s->mode == 'r') { - err = inflateEnd(&(s->stream)); - } - } - if (s->file != NULL && fclose(s->file)) { -#ifdef ESPIPE - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ -#endif - err = Z_ERRNO; - } - if (s->z_err < 0) err = s->z_err; - - TRYFREE(s->inbuf); - TRYFREE(s->outbuf); - TRYFREE(s->path); - TRYFREE(s); - return err; -} - -/* =========================================================================== - Reads the given number of uncompressed bytes from the compressed file. - gzread returns the number of bytes actually read (0 for end of file). -*/ -int ZEXPORT gzread (file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - Bytef *start = (Bytef*)buf; /* starting point for crc computation */ - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ - - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; - - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ - - next_out = (Byte*)buf; - s->stream.next_out = (Bytef*)buf; - s->stream.avail_out = len; - - if (s->stream.avail_out && s->back != EOF) { - *next_out++ = s->back; - s->stream.next_out++; - s->stream.avail_out--; - s->back = EOF; - s->out++; - start++; - if (s->last) { - s->z_err = Z_STREAM_END; - return 1; - } - } - - while (s->stream.avail_out != 0) { - - if (s->transparent) { - /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; - if (n > s->stream.avail_out) n = s->stream.avail_out; - if (n > 0) { - zmemcpy(s->stream.next_out, s->stream.next_in, n); - next_out += n; - s->stream.next_out = next_out; - s->stream.next_in += n; - s->stream.avail_out -= n; - s->stream.avail_in -= n; - } - if (s->stream.avail_out > 0) { - s->stream.avail_out -= - (uInt)fread(next_out, 1, s->stream.avail_out, s->file); - } - len -= s->stream.avail_out; - s->in += len; - s->out += len; - if (len == 0) s->z_eof = 1; - return (int)len; - } - if (s->stream.avail_in == 0 && !s->z_eof) { - - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = inflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - - if (s->z_err == Z_STREAM_END) { - /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - start = s->stream.next_out; - - if (getLong(s) != s->crc) { - s->z_err = Z_DATA_ERROR; - } else { - (void)getLong(s); - /* The uncompressed length returned by above getlong() may be - * different from s->out in case of concatenated .gz files. - * Check for such files: - */ - check_header(s); - if (s->z_err == Z_OK) { - inflateReset(&(s->stream)); - s->crc = crc32(0L, Z_NULL, 0); - } - } - } - if (s->z_err != Z_OK || s->z_eof) break; - } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - - if (len == s->stream.avail_out && - (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) - return -1; - return (int)(len - s->stream.avail_out); -} - - -/* =========================================================================== - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ -int ZEXPORT gzgetc(file) - gzFile file; -{ - unsigned char c; - - return gzread(file, &c, 1) == 1 ? c : -1; -} - - -/* =========================================================================== - Push one byte back onto the stream. -*/ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; - s->back = c; - s->out--; - s->last = (s->z_err == Z_STREAM_END); - if (s->last) s->z_err = Z_OK; - s->z_eof = 0; - return c; -} - - -/* =========================================================================== - Reads bytes from the compressed file until len-1 characters are - read, or a newline character is read and transferred to buf, or an - end-of-file condition is encountered. The string is then terminated - with a null character. - gzgets returns buf, or Z_NULL in case of error. - - The current implementation is not optimized at all. -*/ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - char *b = buf; - if (buf == Z_NULL || len <= 0) return Z_NULL; - - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; - *buf = '\0'; - return b == buf && len > 0 ? Z_NULL : b; -} - - -#ifndef NO_GZCOMPRESS -/* =========================================================================== - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of bytes actually written (0 in case of error). -*/ -int ZEXPORT gzwrite (file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.next_in = (Bytef*)buf; - s->stream.avail_in = len; - - while (s->stream.avail_in != 0) { - - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - break; - } - s->stream.avail_out = Z_BUFSIZE; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - if (s->z_err != Z_OK) break; - } - s->crc = crc32(s->crc, (const Bytef *)buf, len); - - return (int)(len - s->stream.avail_in); -} - - -/* =========================================================================== - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). -*/ -#ifdef STDC -#include - -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) -{ - char buf[Z_PRINTF_BUFSIZE]; - va_list va; - int len; - - buf[sizeof(buf) - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(buf, format, va); - va_end(va); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = vsprintf(buf, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(buf, sizeof(buf), format, va); - va_end(va); - len = strlen(buf); -# else - len = vsnprintf(buf, sizeof(buf), format, va); - va_end(va); -# endif -#endif - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, (unsigned)len); -} -#else /* not ANSI C */ - -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - char buf[Z_PRINTF_BUFSIZE]; - int len; - - buf[sizeof(buf) - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(buf); -# else - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, len); -} -#endif - -/* =========================================================================== - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char cc = (unsigned char) c; /* required for big endian systems */ - - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; -} - - -/* =========================================================================== - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ - return gzwrite(file, (char*)s, (unsigned)strlen(s)); -} - - -/* =========================================================================== - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. -*/ -local int do_flush (file, flush) - gzFile file; - int flush; -{ - uInt len; - int done = 0; - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.avail_in = 0; /* should be zero already anyway */ - - for (;;) { - len = Z_BUFSIZE - s->stream.avail_out; - - if (len != 0) { - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { - s->z_err = Z_ERRNO; - return Z_ERRNO; - } - s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; - } - if (done) break; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), flush); - s->out -= s->stream.avail_out; - - /* Ignore the second of two consecutive flushes: */ - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; - - /* deflate has finished flushing only when it hasn't used up - * all the available space in the output buffer: - */ - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); - - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; - } - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} - -int ZEXPORT gzflush (file, flush) - gzFile file; - int flush; -{ - gz_stream *s = (gz_stream*)file; - int err = do_flush (file, flush); - - if (err) return err; - fflush(s->file); - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} -#endif /* NO_GZCOMPRESS */ - -/* =========================================================================== - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error. - SEEK_END is not implemented, returns error. - In this version of the library, gzseek can be extremely slow. -*/ -z_off_t ZEXPORT gzseek (file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || whence == SEEK_END || - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { - return -1L; - } - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return -1L; -#else - if (whence == SEEK_SET) { - offset -= s->in; - } - if (offset < 0) return -1L; - - /* At this point, offset is the number of zero bytes to write. */ - if (s->inbuf == Z_NULL) { - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ - if (s->inbuf == Z_NULL) return -1L; - zmemzero(s->inbuf, Z_BUFSIZE); - } - while (offset > 0) { - uInt size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (uInt)offset; - - size = gzwrite(file, s->inbuf, size); - if (size == 0) return -1L; - - offset -= size; - } - return s->in; -#endif - } - /* Rest of function is for reading only */ - - /* compute absolute position */ - if (whence == SEEK_CUR) { - offset += s->out; - } - if (offset < 0) return -1L; - - if (s->transparent) { - /* map to fseek */ - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; - - s->in = s->out = offset; - return offset; - } - - /* For a negative seek, rewind and use positive seek */ - if (offset >= s->out) { - offset -= s->out; - } else if (gzrewind(file) < 0) { - return -1L; - } - /* offset is now the number of bytes to skip. */ - - if (offset != 0 && s->outbuf == Z_NULL) { - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); - if (s->outbuf == Z_NULL) return -1L; - } - if (offset && s->back != EOF) { - s->back = EOF; - s->out++; - offset--; - if (s->last) s->z_err = Z_STREAM_END; - } - while (offset > 0) { - int size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (int)offset; - - size = gzread(file, s->outbuf, (uInt)size); - if (size <= 0) return -1L; - offset -= size; - } - return s->out; -} - -/* =========================================================================== - Rewinds input file. -*/ -int ZEXPORT gzrewind (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return -1; - - s->z_err = Z_OK; - s->z_eof = 0; - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - s->crc = crc32(0L, Z_NULL, 0); - if (!s->transparent) (void)inflateReset(&s->stream); - s->in = 0; - s->out = 0; - return fseek(s->file, s->start, SEEK_SET); -} - -/* =========================================================================== - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. -*/ -z_off_t ZEXPORT gztell (file) - gzFile file; -{ - return gzseek(file, 0L, SEEK_CUR); -} - -/* =========================================================================== - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ -int ZEXPORT gzeof (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - /* With concatenated compressed files that can have embedded - * crc trailers, z_eof is no longer the only/best indicator of EOF - * on a gz_stream. Handle end-of-stream error explicitly here. - */ - if (s == NULL || s->mode != 'r') return 0; - if (s->z_eof) return 1; - return s->z_err == Z_STREAM_END; -} - -/* =========================================================================== - Returns 1 if reading and doing so transparently, otherwise zero. -*/ -int ZEXPORT gzdirect (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return 0; - return s->transparent; -} - -/* =========================================================================== - Outputs a long in LSB order to the given file -*/ -local void putLong (file, x) - FILE *file; - uLong x; -{ - int n; - for (n = 0; n < 4; n++) { - fputc((int)(x & 0xff), file); - x >>= 8; - } -} - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets z_err in case - of error. -*/ -local uLong getLong (s) - gz_stream *s; -{ - uLong x = (uLong)get_byte(s); - int c; - - x += ((uLong)get_byte(s))<<8; - x += ((uLong)get_byte(s))<<16; - c = get_byte(s); - if (c == EOF) s->z_err = Z_DATA_ERROR; - x += ((uLong)c)<<24; - return x; -} - -/* =========================================================================== - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. -*/ -int ZEXPORT gzclose (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return Z_STREAM_ERROR; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return Z_STREAM_ERROR; -#else - if (do_flush (file, Z_FINISH) != Z_OK) - return destroy((gz_stream*)file); - - putLong (s->file, s->crc); - putLong (s->file, (uLong)(s->in & 0xffffffff)); -#endif - } - return destroy((gz_stream*)file); -} - -#ifdef STDC -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -/* =========================================================================== - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ -const char * ZEXPORT gzerror (file, errnum) - gzFile file; - int *errnum; -{ - char *m; - gz_stream *s = (gz_stream*)file; - - if (s == NULL) { - *errnum = Z_STREAM_ERROR; - return (const char*)ERR_MSG(Z_STREAM_ERROR); - } - *errnum = s->z_err; - if (*errnum == Z_OK) return (const char*)""; - - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); - - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); - - TRYFREE(s->msg); - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); - strcpy(s->msg, s->path); - strcat(s->msg, ": "); - strcat(s->msg, m); - return (const char*)s->msg; -} - -/* =========================================================================== - Clear the error and end-of-file flags, and do the same for the real file. -*/ -void ZEXPORT gzclearerr (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return; - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; - s->z_eof = 0; - clearerr(s->file); -} diff --git a/lib/3rdparty/zlib/gzlib.c b/lib/3rdparty/zlib/gzlib.c new file mode 100644 index 00000000000..e9eef783fe1 --- /dev/null +++ b/lib/3rdparty/zlib/gzlib.c @@ -0,0 +1,537 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const char *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + if (state->mode == GZ_READ) { /* for reading ... */ + state->have = 0; /* no output data available */ + state->eof = 0; /* not at end of file */ + state->how = LOOK; /* look for gzip header */ + state->direct = 1; /* default for empty file */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gz_statep state; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* save the path name for error messages */ + state->path = malloc(strlen(path) + 1); + if (state->path == NULL) { + free(state); + return NULL; + } + strcpy(state->path, path); + + /* open the file with the appropriate mode (or just use fd) */ + state->fd = fd != -1 ? fd : + open(path, +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | ( + state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))), + 0666); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size == 0) + return -1; + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->pos + offset >= state->raw) { + ret = LSEEK(state->fd, offset - state->have, SEEK_CUR); + if (ret == -1) + return -1; + state->have = 0; + state->eof = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->pos += offset; + return state->pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->have) || (z_off64_t)state->have > offset ? + (unsigned)offset : state->have; + state->have -= n; + state->next += n; + state->pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? + (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) + state->eof = 0; + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/lib/3rdparty/zlib/gzread.c b/lib/3rdparty/zlib/gzread.c new file mode 100644 index 00000000000..548201ab009 --- /dev/null +++ b/lib/3rdparty/zlib/gzread.c @@ -0,0 +1,653 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_next4 OF((gz_statep, unsigned long *)); +local int gz_head OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_make OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + gz_avail() assumes that strm->avail_in == 0. */ +local int gz_avail(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + if (state->err != Z_OK) + return -1; + if (state->eof == 0) { + if (gz_load(state, state->in, state->size, + (unsigned *)&(strm->avail_in)) == -1) + return -1; + strm->next_in = state->in; + } + return 0; +} + +/* Get next byte from input, or -1 if end or error. */ +#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ + (strm->avail_in == 0 ? -1 : \ + (strm->avail_in--, *(strm->next_in)++))) + +/* Get a four-byte little-endian integer and return 0 on success and the value + in *ret. Otherwise -1 is returned and *ret is not modified. */ +local int gz_next4(state, ret) + gz_statep state; + unsigned long *ret; +{ + int ch; + unsigned long val; + z_streamp strm = &(state->strm); + + val = NEXT(); + val += (unsigned)NEXT() << 8; + val += (unsigned long)NEXT() << 16; + ch = NEXT(); + if (ch == -1) + return -1; + val += (unsigned long)ch << 24; + *ret = val; + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->have must be zero. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression, and the gzip header will be skipped so + that the next available input data is the raw deflate stream. If direct + copying, then leftover input data from the input buffer will be copied to + the output buffer. In that case, all further file reads will be directly to + either the output buffer or a user buffer. If decompressing, the inflate + state and the check value will be initialized. gz_head() will return 0 on + success or -1 on failure. Failures may include read errors or gzip header + errors. */ +local int gz_head(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + int flags; + unsigned len; + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get some data in the input buffer */ + if (strm->avail_in == 0) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for the gzip magic header bytes 31 and 139 */ + if (strm->next_in[0] == 31) { + strm->avail_in--; + strm->next_in++; + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in && strm->next_in[0] == 139) { + /* we have a gzip header, woo hoo! */ + strm->avail_in--; + strm->next_in++; + + /* skip rest of header */ + if (NEXT() != 8) { /* compression method */ + gz_error(state, Z_DATA_ERROR, "unknown compression method"); + return -1; + } + flags = NEXT(); + if (flags & 0xe0) { /* reserved flag bits */ + gz_error(state, Z_DATA_ERROR, "unknown header flags set"); + return -1; + } + NEXT(); /* modification time */ + NEXT(); + NEXT(); + NEXT(); + NEXT(); /* extra flags */ + NEXT(); /* operating system */ + if (flags & 4) { /* extra field */ + len = (unsigned)NEXT(); + len += (unsigned)NEXT() << 8; + while (len--) + if (NEXT() < 0) + break; + } + if (flags & 8) /* file name */ + while (NEXT() > 0) + ; + if (flags & 16) /* comment */ + while (NEXT() > 0) + ; + if (flags & 2) { /* header crc */ + NEXT(); + NEXT(); + } + /* an unexpected end of file is not checked for here -- it will be + noticed on the first request for uncompressed data */ + + /* set up for decompression */ + inflateReset(strm); + strm->adler = crc32(0L, Z_NULL, 0); + state->how = GZIP; + state->direct = 0; + return 0; + } + else { + /* not a gzip file -- save first byte (31) and fall to raw i/o */ + state->out[0] = 31; + state->have = 1; + } + } + + /* doing raw i/o, save start of raw data for seeking, copy any leftover + input to output -- this assumes that the output buffer is larger than + the input buffer, which also assures space for gzungetc() */ + state->raw = state->pos; + state->next = state->out; + if (strm->avail_in) { + memcpy(state->next + state->have, strm->next_in, strm->avail_in); + state->have += strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + If the end of the compressed data is reached, then verify the gzip trailer + check value and length (modulo 2^32). state->have and state->next are set + to point to the just decompressed data, and the crc is updated. If the + trailer is verified, state->how is reset to LOOK to look for the next gzip + stream or raw data, once state->have is depleted. Returns 0 on success, -1 + on failure. Failures may include invalid compressed data or a failed gzip + trailer verification. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret; + unsigned had; + unsigned long crc, len; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_DATA_ERROR, "unexpected end of file"); + return -1; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output and crc check value */ + state->have = had - strm->avail_out; + state->next = strm->next_out - state->have; + strm->adler = crc32(strm->adler, state->next, state->have); + + /* check gzip trailer if at end of deflate stream */ + if (ret == Z_STREAM_END) { + if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { + gz_error(state, Z_DATA_ERROR, "unexpected end of file"); + return -1; + } + if (crc != strm->adler) { + gz_error(state, Z_DATA_ERROR, "incorrect data check"); + return -1; + } + if (len != (strm->total_out & 0xffffffffL)) { + gz_error(state, Z_DATA_ERROR, "incorrect length check"); + return -1; + } + state->how = LOOK; /* ready for next stream, once have is 0 (leave + state->direct unchanged to remember how) */ + } + + /* good decompression */ + return 0; +} + +/* Make data and put in the output buffer. Assumes that state->have == 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for (and skipped if found) to determine wither to copy or decompress. + Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY + or GZIP unless the end of the input file has been reached and all data has + been processed. */ +local int gz_make(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + if (state->how == LOOK) { /* look for gzip header */ + if (gz_head(state) == -1) + return -1; + if (state->have) /* got some data from gz_head() */ + return 0; + } + if (state->how == COPY) { /* straight copy */ + if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) + return -1; + state->next = state->out; + } + else if (state->how == GZIP) { /* decompress */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->have) { + n = GT_OFF(state->have) || (z_off64_t)state->have > len ? + (unsigned)len : state->have; + state->have -= n; + state->next += n; + state->pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_make(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->have) { + n = state->have > len ? len : state->have; + memcpy(buf, state->next, n); + state->next += n; + state->have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) + break; + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_make(state) == -1) + return -1; + continue; /* no progress yet -- go back to memcpy() above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->have; + state->have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->have) { + state->have--; + state->pos++; + return *(state->next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->have == 0) { + state->have = 1; + state->next = state->out + (state->size << 1) - 1; + state->next[0] = c; + state->pos--; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->have == (state->size << 1)) { + gz_error(state, Z_BUF_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->next == state->out) { + unsigned char *src = state->out + state->have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->next = dest; + } + state->have++; + state->next--; + state->next[0] = c; + state->pos--; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || state->err != Z_OK) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->have == 0) { + if (gz_make(state) == -1) + return NULL; /* error */ + if (state->have == 0) { /* end of file */ + if (buf == str) /* got bupkus */ + return NULL; + break; /* got something -- return it */ + } + } + + /* look for end-of-line in current output buffer */ + n = state->have > left ? left : state->have; + eol = memchr(state->next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->next, n); + state->have -= n; + state->next += n; + state->pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* found end-of-line or out of space -- terminate string and return it */ + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return 0; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->how == LOOK && state->have == 0) + (void)gz_head(state); + + /* return 1 if reading direct, 0 if decompressing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : Z_OK; +} diff --git a/lib/3rdparty/zlib/gzwrite.c b/lib/3rdparty/zlib/gzwrite.c new file mode 100644 index 00000000000..e8defc6887a --- /dev/null +++ b/lib/3rdparty/zlib/gzwrite.c @@ -0,0 +1,531 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input and output buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + 15 + 16, 8, state->strategy); + if (ret != Z_OK) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer */ + strm->avail_out = state->size; + strm->next_out = state->out; + state->next = strm->next_out; + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->next); + if (have && ((got = write(state->fd, state->next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->pos++; + return c; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#ifdef STDC +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(state->in, format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf(state->in, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(state->in, size, format, va); + va_end(va); + len = strlen(state->in); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->pos += len; + return len; +} + +#else /* !STDC */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(state->in); +# else + len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = 0; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + ret += gz_zero(state, state->skip); + } + + /* flush, free memory, and close file */ + ret += gz_comp(state, Z_FINISH); + (void)deflateEnd(&(state->strm)); + free(state->out); + free(state->in); + gz_error(state, Z_OK, NULL); + free(state->path); + ret += close(state->fd); + free(state); + return ret ? Z_ERRNO : Z_OK; +} diff --git a/lib/3rdparty/zlib/infback.c b/lib/3rdparty/zlib/infback.c index 455dbc9ee84..af3a8c965d5 100644 --- a/lib/3rdparty/zlib/infback.c +++ b/lib/3rdparty/zlib/infback.c @@ -1,5 +1,5 @@ /* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -55,7 +55,7 @@ int stream_size; state->wbits = windowBits; state->wsize = 1U << windowBits; state->window = window; - state->write = 0; + state->wnext = 0; state->whave = 0; return Z_OK; } @@ -253,7 +253,7 @@ void FAR *out_desc; unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ + code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ @@ -389,19 +389,19 @@ void FAR *out_desc; state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; } else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; @@ -411,16 +411,16 @@ void FAR *out_desc; copy = 3 + BITS(2); DROPBITS(2); } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); @@ -438,7 +438,16 @@ void FAR *out_desc; /* handle error breaks in while */ if (state->mode == BAD) break; - /* build code tables */ + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; @@ -474,28 +483,28 @@ void FAR *out_desc; /* get a literal, length, or end-of-block code */ for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.op && (this.op & 0xf0) == 0) { - last = this; + if (here.op && (here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->lencode[last.val + + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } - DROPBITS(this.bits); - state->length = (unsigned)this.val; + DROPBITS(here.bits); + state->length = (unsigned)here.val; /* process literal */ - if (this.op == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); + "inflate: literal 0x%02x\n", here.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; @@ -504,21 +513,21 @@ void FAR *out_desc; } /* process end of block */ - if (this.op & 32) { + if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ - if (this.op & 64) { + if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; + state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); @@ -528,30 +537,30 @@ void FAR *out_desc; /* get distance code */ for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if ((this.op & 0xf0) == 0) { - last = this; + if ((here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->distcode[last.val + + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } - DROPBITS(this.bits); - if (this.op & 64) { + DROPBITS(here.bits); + if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } - state->offset = (unsigned)this.val; + state->offset = (unsigned)here.val; /* get distance extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; + state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); diff --git a/lib/3rdparty/zlib/inffast.c b/lib/3rdparty/zlib/inffast.c index bbee92ed1e6..a9e584fbd25 100644 --- a/lib/3rdparty/zlib/inffast.c +++ b/lib/3rdparty/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2004 Mark Adler + * Copyright (C) 1995-2008, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -79,7 +79,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ + unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ @@ -87,7 +87,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ - code this; /* retrieved table entry */ + code here; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ @@ -106,7 +106,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ #endif wsize = state->wsize; whave = state->whave; - write = state->write; + wnext = state->wnext; window = state->window; hold = state->hold; bits = state->bits; @@ -124,20 +124,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold += (unsigned long)(PUP(in)) << bits; bits += 8; } - this = lcode[hold & lmask]; + here = lcode[hold & lmask]; dolen: - op = (unsigned)(this.bits); + op = (unsigned)(here.bits); hold >>= op; bits -= op; - op = (unsigned)(this.op); + op = (unsigned)(here.op); if (op == 0) { /* literal */ - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - PUP(out) = (unsigned char)(this.val); + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); } else if (op & 16) { /* length base */ - len = (unsigned)(this.val); + len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { @@ -155,14 +155,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold += (unsigned long)(PUP(in)) << bits; bits += 8; } - this = dcode[hold & dmask]; + here = dcode[hold & dmask]; dodist: - op = (unsigned)(this.bits); + op = (unsigned)(here.bits); hold >>= op; bits -= op; - op = (unsigned)(this.op); + op = (unsigned)(here.op); if (op & 16) { /* distance base */ - dist = (unsigned)(this.val); + dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; @@ -187,12 +187,34 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif } from = window - OFF; - if (write == 0) { /* very common case */ + if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; @@ -202,17 +224,17 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ from = out - dist; /* rest from output */ } } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; + if (wnext < len) { /* some from start of window */ + op = wnext; len -= op; do { PUP(out) = PUP(from); @@ -222,7 +244,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else { /* contiguous in window */ - from += write - op; + from += wnext - op; if (op < len) { /* some from window */ len -= op; do { @@ -259,7 +281,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else if ((op & 64) == 0) { /* 2nd level distance code */ - this = dcode[this.val + (hold & ((1U << op) - 1))]; + here = dcode[here.val + (hold & ((1U << op) - 1))]; goto dodist; } else { @@ -269,7 +291,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else if ((op & 64) == 0) { /* 2nd level length code */ - this = lcode[this.val + (hold & ((1U << op) - 1))]; + here = lcode[here.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ @@ -305,7 +327,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 + - Three separate decoding do-loops for direct, window, and wnext == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes diff --git a/lib/3rdparty/zlib/inffast.h b/lib/3rdparty/zlib/inffast.h index 1e88d2d97b5..4d5c03abdd5 100644 --- a/lib/3rdparty/zlib/inffast.h +++ b/lib/3rdparty/zlib/inffast.h @@ -1,5 +1,5 @@ /* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler + * Copyright (C) 1995-2003, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/lib/3rdparty/zlib/inflate.c b/lib/3rdparty/zlib/inflate.c index 792fdee8e9c..a8431abeacf 100644 --- a/lib/3rdparty/zlib/inflate.c +++ b/lib/3rdparty/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -45,7 +45,7 @@ * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() + * - Pull out common wnext == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() @@ -117,28 +117,52 @@ z_streamp strm; state->head = Z_NULL; state->wsize = 0; state->whave = 0; - state->write = 0; + state->wnext = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; Tracev((stderr, "inflate: reset\n")); return Z_OK; } -int ZEXPORT inflatePrime(strm, bits, value) +int ZEXPORT inflateReset2(strm, windowBits) z_streamp strm; -int bits; -int value; +int windowBits; { + int wrap; struct inflate_state FAR *state; + /* get the state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) @@ -147,6 +171,7 @@ int windowBits; const char *version; int stream_size; { + int ret; struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || @@ -164,24 +189,13 @@ int stream_size; if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { ZFREE(strm, state); strm->state = Z_NULL; - return Z_STREAM_ERROR; } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); + return ret; } int ZEXPORT inflateInit_(strm, version, stream_size) @@ -192,6 +206,27 @@ int stream_size; return inflateInit2_(strm, DEF_WBITS, version, stream_size); } +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. @@ -340,7 +375,7 @@ unsigned out; /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; - state->write = 0; + state->wnext = 0; state->whave = 0; } @@ -348,22 +383,22 @@ unsigned out; copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; + state->wnext = 0; state->whave = state->wsize; } else { - dist = state->wsize - state->write; + dist = state->wsize - state->wnext; if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; + state->wnext = copy; state->whave = state->wsize; } else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; if (state->whave < state->wsize) state->whave += dist; } } @@ -564,7 +599,7 @@ int flush; unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ + code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ @@ -619,7 +654,9 @@ int flush; } DROPBITS(4); len = BITS(4) + 8; - if (len > state->wbits) { + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; @@ -771,7 +808,7 @@ int flush; strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: - if (flush == Z_BLOCK) goto inf_leave; + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); @@ -791,7 +828,11 @@ int flush; fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", @@ -816,6 +857,9 @@ int flush; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: state->mode = COPY; case COPY: copy = state->length; @@ -876,19 +920,19 @@ int flush; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; } else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; @@ -898,16 +942,16 @@ int flush; copy = 3 + BITS(2); DROPBITS(2); } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); @@ -925,7 +969,16 @@ int flush; /* handle error breaks in while */ if (state->mode == BAD) break; - /* build code tables */ + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; @@ -946,88 +999,102 @@ int flush; break; } Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); + if (state->mode == TYPE) + state->back = -1; break; } + state->back = 0; for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if (this.op && (this.op & 0xf0) == 0) { - last = this; + if (here.op && (here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->lencode[last.val + + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); + state->back += last.bits; } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - if ((int)(this.op) == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); + "inflate: literal 0x%02x\n", here.val)); state->mode = LIT; break; } - if (this.op & 32) { + if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; state->mode = TYPE; break; } - if (this.op & 64) { + if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } - state->extra = (unsigned)(this.op) & 15; + state->extra = (unsigned)(here.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); + state->back += state->extra; } Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; state->mode = DIST; case DIST: for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } - if ((this.op & 0xf0) == 0) { - last = this; + if ((here.op & 0xf0) == 0) { + last = here; for (;;) { - this = state->distcode[last.val + + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; + if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); + state->back += last.bits; } - DROPBITS(this.bits); - if (this.op & 64) { + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } - state->offset = (unsigned)this.val; - state->extra = (unsigned)(this.op) & 15; + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); + state->back += state->extra; } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { @@ -1036,11 +1103,6 @@ int flush; break; } #endif - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: @@ -1048,12 +1110,32 @@ int flush; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; from = state->window + (state->wsize - copy); } else - from = state->window + (state->write - copy); + from = state->window + (state->wnext - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ @@ -1146,7 +1228,8 @@ int flush; strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; @@ -1366,3 +1449,32 @@ z_streamp source; dest->state = (struct internal_state FAR *)copy; return Z_OK; } + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/lib/3rdparty/zlib/inflate.h b/lib/3rdparty/zlib/inflate.h index 07bd3e78a7c..95f4986d400 100644 --- a/lib/3rdparty/zlib/inflate.h +++ b/lib/3rdparty/zlib/inflate.h @@ -1,5 +1,5 @@ /* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2004 Mark Adler + * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -32,11 +32,13 @@ typedef enum { TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ @@ -53,19 +55,21 @@ typedef enum { /* State transitions between above modes - - (most modes can go to the BAD or MEM mode -- not shown for clarity) + (most modes can go to BAD or MEM on error -- not shown for clarity) Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE + (raw) -> TYPEDO Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN @@ -73,7 +77,7 @@ typedef enum { CHECK -> LENGTH -> DONE */ -/* state maintained between inflate() calls. Approximately 7K bytes. */ +/* state maintained between inflate() calls. Approximately 10K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ @@ -88,7 +92,7 @@ struct inflate_state { unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ + unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ @@ -112,4 +116,7 @@ struct inflate_state { unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ }; diff --git a/lib/3rdparty/zlib/inftrees.c b/lib/3rdparty/zlib/inftrees.c index 8a9c13ff03d..6f7afcb306d 100644 --- a/lib/3rdparty/zlib/inftrees.c +++ b/lib/3rdparty/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; + " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -50,7 +50,7 @@ unsigned short FAR *work; unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ - code this; /* table entry for duplication */ + code here; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, @@ -115,15 +115,15 @@ unsigned short FAR *work; if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)1; - this.val = (unsigned short)0; - *(*table)++ = this; /* make a table to force an error */ - *(*table)++ = this; + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } - for (min = 1; min <= MAXBITS; min++) + for (min = 1; min < max; min++) if (count[min] != 0) break; if (root < min) root = min; @@ -166,11 +166,10 @@ unsigned short FAR *work; entered in the tables. used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This @@ -209,24 +208,25 @@ unsigned short FAR *work; mask = used - 1; /* mask for comparing low */ /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ - this.bits = (unsigned char)(len - drop); + here.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { - this.op = (unsigned char)0; - this.val = work[sym]; + here.op = (unsigned char)0; + here.val = work[sym]; } else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; } else { - this.op = (unsigned char)(32 + 64); /* end of block */ - this.val = 0; + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; } /* replicate for those indices with low len bits equal to huff */ @@ -235,7 +235,7 @@ unsigned short FAR *work; min = fill; /* save offset to next table */ do { fill -= incr; - next[(huff >> drop) + fill] = this; + next[(huff >> drop) + fill] = here; } while (fill != 0); /* backwards increment the len-bit code huff */ @@ -277,7 +277,8 @@ unsigned short FAR *work; /* check for enough space */ used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ @@ -295,20 +296,20 @@ unsigned short FAR *work; through high index bits. When the current sub-table is filled, the loop drops back to the root table to fill in any remaining entries there. */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)(len - drop); - this.val = (unsigned short)0; + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; while (huff != 0) { /* when done with sub-table, drop back to root table */ if (drop != 0 && (huff & mask) != low) { drop = 0; len = root; next = *table; - this.bits = (unsigned char)len; + here.bits = (unsigned char)len; } /* put invalid code marker in table */ - next[huff >> drop] = this; + next[huff >> drop] = here; /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); diff --git a/lib/3rdparty/zlib/inftrees.h b/lib/3rdparty/zlib/inftrees.h index b1104c87e76..3098b6513a6 100644 --- a/lib/3rdparty/zlib/inftrees.h +++ b/lib/3rdparty/zlib/inftrees.h @@ -1,5 +1,5 @@ /* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005 Mark Adler + * Copyright (C) 1995-2005, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -35,21 +35,28 @@ typedef struct { 01000000 - invalid code */ -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1444 code structures (852 for length/literals - and 592 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 2048 -#define MAXD 592 +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) -/* Type of code to build for inftable() */ +/* Type of code to build for inflate_table() */ typedef enum { CODES, LENS, DISTS } codetype; -extern int inflate_table OF((codetype type, unsigned short FAR *lens, +int inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)); diff --git a/lib/3rdparty/zlib/minigzip.c b/lib/3rdparty/zlib/minigzip.c index 4524b96a1d6..9825ccc3a71 100644 --- a/lib/3rdparty/zlib/minigzip.c +++ b/lib/3rdparty/zlib/minigzip.c @@ -1,5 +1,5 @@ /* minigzip.c -- simulate gzip using the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2006, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -15,8 +15,8 @@ /* @(#) $Id$ */ -#include #include "zlib.h" +#include #ifdef STDC # include @@ -32,6 +32,9 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include # include +# ifdef UNDER_CE +# include +# endif # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) @@ -50,9 +53,75 @@ # include /* for fileno */ #endif +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) #ifndef WIN32 /* unlink already in stdio.h for WIN32 */ extern int unlink OF((const char *)); #endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ #ifndef GZ_SUFFIX # define GZ_SUFFIX ".gz" @@ -198,6 +267,11 @@ void file_compress(file, mode) FILE *in; gzFile out; + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + strcpy(outfile, file); strcat(outfile, GZ_SUFFIX); @@ -227,7 +301,12 @@ void file_uncompress(file) char *infile, *outfile; FILE *out; gzFile in; - uInt len = (uInt)strlen(file); + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } strcpy(buf, file); @@ -258,7 +337,8 @@ void file_uncompress(file) /* =========================================================================== - * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output * -d : decompress * -f : compress with Z_FILTERED * -h : compress with Z_HUFFMAN_ONLY @@ -270,17 +350,30 @@ int main(argc, argv) int argc; char *argv[]; { + int copyout = 0; int uncompr = 0; gzFile file; - char outmode[20]; + char *bname, outmode[20]; strcpy(outmode, "wb6 "); prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; argc--, argv++; + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + while (argc > 0) { - if (strcmp(*argv, "-d") == 0) + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) uncompr = 1; else if (strcmp(*argv, "-f") == 0) outmode[3] = 'f'; @@ -310,11 +403,36 @@ int main(argc, argv) gz_compress(stdin, file); } } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } do { if (uncompr) { - file_uncompress(*argv); + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } } else { - file_compress(*argv, outmode); + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } } } while (argv++, --argc); } diff --git a/lib/3rdparty/zlib/trees.c b/lib/3rdparty/zlib/trees.c index 395e4e16814..a05ec378b3a 100644 --- a/lib/3rdparty/zlib/trees.c +++ b/lib/3rdparty/zlib/trees.c @@ -1,5 +1,6 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -152,7 +153,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, ct_data *ltree, ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); +local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); @@ -203,12 +204,12 @@ local void send_bits(s, value, length) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); + s->bi_buf |= (ush)value << s->bi_valid; put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { - s->bi_buf |= value << s->bi_valid; + s->bi_buf |= (ush)value << s->bi_valid; s->bi_valid += length; } } @@ -218,12 +219,12 @@ local void send_bits(s, value, length) { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ + s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ - s->bi_buf |= (value) << s->bi_valid;\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ s->bi_valid += len;\ }\ } @@ -250,11 +251,13 @@ local void tr_static_init() if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; +#endif /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; @@ -348,13 +351,14 @@ void gen_trees_header() static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); @@ -864,13 +868,13 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) /* =========================================================================== * Send a stored block */ -void _tr_stored_block(s, buf, stored_len, eof) +void _tr_stored_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ + int last; /* one if this is the last block for a file */ { - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ #ifdef DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; @@ -918,11 +922,11 @@ void _tr_align(s) * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ -void _tr_flush_block(s, buf, stored_len, eof) +void _tr_flush_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ + int last; /* one if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ @@ -931,8 +935,8 @@ void _tr_flush_block(s, buf, stored_len, eof) if (s->level > 0) { /* Check if the file is binary or text */ - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) - set_data_type(s); + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); @@ -978,20 +982,20 @@ void _tr_flush_block(s, buf, stored_len, eof) * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ - _tr_stored_block(s, buf, stored_len, eof); + _tr_stored_block(s, buf, stored_len, last); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); + send_bits(s, (STATIC_TREES<<1)+last, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); + send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); @@ -1005,14 +1009,14 @@ void _tr_flush_block(s, buf, stored_len, eof) */ init_block(s); - if (eof) { + if (last) { bi_windup(s); #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); + s->compressed_len-7*last)); } /* =========================================================================== @@ -1118,24 +1122,45 @@ local void compress_block(s, ltree, dtree) } /* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). * IN assertion: the fields Freq of dyn_ltree are set. */ -local void set_data_type(s) +local int detect_data_type(s) deflate_state *s; { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; int n; - for (n = 0; n < 9; n++) + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) if (s->dyn_ltree[n].Freq != 0) - break; - if (n == 9) - for (n = 14; n < 32; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; } /* =========================================================================== diff --git a/lib/3rdparty/zlib/uncompr.c b/lib/3rdparty/zlib/uncompr.c index b59e3d0defb..ad98be3a5d8 100644 --- a/lib/3rdparty/zlib/uncompr.c +++ b/lib/3rdparty/zlib/uncompr.c @@ -1,5 +1,5 @@ /* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -16,8 +16,6 @@ been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output diff --git a/lib/3rdparty/zlib/zconf.h b/lib/3rdparty/zlib/zconf.h index 03a9431c8be..02ce56c4313 100644 --- a/lib/3rdparty/zlib/zconf.h +++ b/lib/3rdparty/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -11,52 +11,124 @@ /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 # define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress # define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func +/* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong # define Bytef z_Bytef +# define alloc_func z_alloc_func # define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func # define intf z_intf +# define out_func z_out_func +# define uInt z_uInt # define uIntf z_uIntf +# define uLong z_uLong # define uLongf z_uLongf -# define voidpf z_voidpf # define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + #endif #if defined(__MSDOS__) && !defined(MSDOS) @@ -284,49 +356,73 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H #endif + +#ifdef STDC +# include /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif + #ifndef z_off_t # define z_off_t long #endif +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + #if defined(__OS400__) # define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ diff --git a/lib/3rdparty/zlib/zconf.in.h b/lib/3rdparty/zlib/zconf.in.h deleted file mode 100644 index 03a9431c8be..00000000000 --- a/lib/3rdparty/zlib/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/lib/3rdparty/zlib/zlib.h b/lib/3rdparty/zlib/zlib.h index 022817927ce..bfbba83e8ee 100644 --- a/lib/3rdparty/zlib/zlib.h +++ b/lib/3rdparty/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 + version 1.2.5, April 19th, 2010 - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,41 +37,44 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 /* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output (providing more output space) before each call. - The compressed data format used by default by the in-memory functions is + The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. - The library also supports reading and writing files in gzip (.gz) format + The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - This library can optionally read and write gzip streams in memory as well. + This library can optionally read and write gzip streams in memory as well. - The zlib format was designed to be compact and fast for use in memory + The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); @@ -126,45 +129,45 @@ typedef struct gz_header_s { typedef gz_header FAR *gz_headerp; /* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the opaque value. - zalloc must return Z_NULL if there is not enough memory for the object. + zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_PARTIAL_FLUSH 1 #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 +#define Z_TREES 6 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 @@ -176,8 +179,8 @@ typedef gz_header FAR *gz_headerp; #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 @@ -207,119 +210,140 @@ typedef gz_header FAR *gz_headerp; #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ + /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when forced to flush. - The detailed semantics are as follows. deflate performs one or both of the + The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not + accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. + accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to + decide how much data to accumulate before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ @@ -328,13 +352,13 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. + This function discards any unprocessed input and does not flush any pending + output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be deallocated). */ @@ -342,10 +366,10 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - Initializes the internal stream state for decompression. The fields + Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to @@ -353,95 +377,108 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce + buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. - The detailed semantics are as follows. inflate performs one or both of the + The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation + first call. So the only effect of the flush parameter in this implementation is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. + because Z_BLOCK or Z_TREES is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 + below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has @@ -449,27 +486,28 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. + This function discards any unprocessed input and does not flush any pending + output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a + was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ + /* Advanced functions */ /* @@ -484,55 +522,57 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int memLevel, int strategy)); - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. - The method parameter is the compression method. It must be Z_DEFLATED in + The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. - windowBits can also be greater than 15 for optional gzip encoding. Add + windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a gzip stream is being written, strm->adler is a crc32 instead of an adler32. The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. - The strategy parameter is used to tune the compression algorithm. Use the + The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, @@ -540,37 +580,37 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a + used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value + which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not + or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ @@ -581,26 +621,26 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed + data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and + (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, @@ -610,18 +650,18 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, @@ -645,9 +685,10 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, @@ -655,21 +696,21 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head)); /* - deflateSetHeader() provides gzip header information for when a gzip + deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information @@ -682,11 +723,11 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. - If deflateSetHeader is not used, the default gzip header has text false, + If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ @@ -694,43 +735,50 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); - This is another version of inflateInit with an extra parameter. The + This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window + deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This + looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom + such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments + most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. - windowBits can also be greater than 15 for optional gzip decoding. Add + windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, @@ -738,8 +786,8 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called @@ -748,26 +796,26 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not + expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, @@ -782,18 +830,30 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and + (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. */ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, @@ -801,54 +861,87 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int value)); /* This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head)); /* - inflateGetHeader() requests that gzip header information be stored in the + inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. - The text, time, xflags, and os fields are filled in with the gzip header + The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max + was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. - If inflateGetHeader is not used, then the header information is simply + If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ @@ -869,9 +962,9 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); @@ -891,15 +984,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then @@ -925,7 +1018,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These @@ -935,15 +1028,15 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); @@ -999,23 +1092,22 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* utility functions */ /* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. @@ -1025,11 +1117,11 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* - Compresses the source buffer into the destination buffer. The level + Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the + length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough @@ -1040,22 +1132,20 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output @@ -1063,136 +1153,199 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, */ -typedef voidp gzFile; + /* gzip file access functions */ -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); /* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* - Dynamically update the compression level or strategy. See the description + Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. */ -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); /* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* - Writes the given null-terminated string to the compressed file, excluding + Writes the given null-terminated string to the compressed file, excluding the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. + + gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. */ -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); /* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are + extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. - gzseek returns the resulting offset location as measured in bytes from + gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. @@ -1202,68 +1355,127 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. */ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* - Returns 1 if file is being read directly without decompression, otherwise - zero. + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ + /* checksum functions */ /* These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. + anyway because they might be useful in applications using the compression + library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: uLong adler = adler32(0L, Z_NULL, 0); @@ -1273,9 +1485,10 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ +/* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); -/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of @@ -1285,9 +1498,11 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + Usage example: uLong crc = crc32(0L, Z_NULL, 0); @@ -1298,9 +1513,9 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ +/* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); -/* Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 @@ -1339,16 +1554,57 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) + ZLIB_VERSION, sizeof(z_stream)) - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); #ifdef __cplusplus } diff --git a/lib/3rdparty/zlib/zlib.rbuild b/lib/3rdparty/zlib/zlib.rbuild index 27082adfacb..c10e794ee05 100644 --- a/lib/3rdparty/zlib/zlib.rbuild +++ b/lib/3rdparty/zlib/zlib.rbuild @@ -1,34 +1,40 @@ - + . adler32.c compress.c crc32.c - gzio.c - uncompr.c deflate.c - trees.c - zutil.c - inflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c infback.c - inftrees.c inffast.c + inflate.c + inftrees.c + trees.c + uncompr.c + zutil.c - + . adler32.c compress.c crc32.c - gzio.c - uncompr.c deflate.c - trees.c - zutil.c - inflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c infback.c - inftrees.c inffast.c + inflate.c + inftrees.c + trees.c + uncompr.c + zutil.c diff --git a/lib/3rdparty/zlib/zutil.c b/lib/3rdparty/zlib/zutil.c index d55f5948a37..e2880ea35d0 100644 --- a/lib/3rdparty/zlib/zutil.c +++ b/lib/3rdparty/zlib/zutil.c @@ -1,5 +1,5 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -34,25 +34,25 @@ uLong ZEXPORT zlibCompileFlags() uLong flags; flags = 0; - switch (sizeof(uInt)) { + switch ((int)(sizeof(uInt))) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } - switch (sizeof(uLong)) { + switch ((int)(sizeof(uLong))) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } - switch (sizeof(voidpf)) { + switch ((int)(sizeof(voidpf))) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } - switch (sizeof(z_off_t)) { + switch ((int)(sizeof(z_off_t))) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; @@ -237,7 +237,7 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) return buf; } -void zcfree (voidpf opaque, voidpf ptr) +void zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ @@ -272,13 +272,13 @@ void zcfree (voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +voidpf zcalloc (voidpf opaque, uInt items, uInt size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } -void zcfree (voidpf opaque, voidpf ptr) +void zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); @@ -307,7 +307,7 @@ voidpf zcalloc (opaque, items, size) (voidpf)calloc(items, size); } -void zcfree (opaque, ptr) +void zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { diff --git a/lib/3rdparty/zlib/zutil.h b/lib/3rdparty/zlib/zutil.h index b7d5eff81b6..69f84f17ccd 100644 --- a/lib/3rdparty/zlib/zutil.h +++ b/lib/3rdparty/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. + * Copyright (C) 1995-2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -13,31 +13,21 @@ #ifndef ZUTIL_H #define ZUTIL_H -#define ZLIB_INTERNAL +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + #include "zlib.h" #ifdef STDC -# ifndef _WIN32_WCE +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # include # endif # include # include #endif -#ifdef NO_ERRNO_H -# ifdef _WIN32_WCE - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. We rename it to - * avoid conflict with other libraries that use the same workaround. - */ -# define errno z_errno -# endif - extern int errno; -#else -# ifndef _WIN32_WCE -# include -# endif -#endif #ifndef local # define local static @@ -89,7 +79,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); @@ -118,7 +108,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #ifdef OS2 # define OS_CODE 0x06 # ifdef M_I86 - #include +# include # endif #endif @@ -151,7 +141,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define fdopen(fd,mode) NULL /* No fdopen() */ #endif -#if (defined(_MSC_VER) && (_MSC_VER > 600)) +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED @@ -163,6 +153,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif +#if defined(__BORLANDC__) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + /* common defaults */ #ifndef OS_CODE @@ -197,7 +199,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif # endif # endif # ifdef __SASC @@ -232,16 +236,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemzero(dest, len) memset(dest, 0, len) # endif #else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); + void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG # include - extern int z_verbose; - extern void z_error OF((char *m)); + extern int _verbose; + extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} @@ -258,8 +262,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); +voidpf zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) diff --git a/lib/drivers/ip/transport/tcp/tcp.c b/lib/drivers/ip/transport/tcp/tcp.c index 187c9a56cc7..e033ff6b6ec 100644 --- a/lib/drivers/ip/transport/tcp/tcp.c +++ b/lib/drivers/ip/transport/tcp/tcp.c @@ -574,10 +574,11 @@ NTSTATUS TCPTranslateError( int OskitError ) { switch( OskitError ) { case 0: Status = STATUS_SUCCESS; break; case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break; + case OSK_EADDRINUSE: Status = STATUS_ADDRESS_ALREADY_EXISTS; break; case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break; case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break; - case OSK_ECONNRESET: - case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break; + case OSK_ECONNRESET: Status = STATUS_REMOTE_DISCONNECT; break; + case OSK_ECONNABORTED: Status = STATUS_LOCAL_DISCONNECT; break; case OSK_EWOULDBLOCK: case OSK_EINPROGRESS: Status = STATUS_PENDING; break; case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break; diff --git a/lib/drivers/oskittcp/oskittcp/rtsock.c b/lib/drivers/oskittcp/oskittcp/rtsock.c index 5654b7b41f6..b7caadc5eab 100644 --- a/lib/drivers/oskittcp/oskittcp/rtsock.c +++ b/lib/drivers/oskittcp/oskittcp/rtsock.c @@ -277,7 +277,7 @@ route_output(m, so) #ifndef __REACTOS__ ifp = ifa->ifa_ifp; #else - ; + (void)0; #endif if (ifa) { register struct ifaddr *oifa = rt->rt_ifa; diff --git a/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c b/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c index f248a48e400..9cfa0d941e6 100644 --- a/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c +++ b/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c @@ -24,11 +24,11 @@ DWORD APIENTRY auxMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/lib/drivers/sound/mmebuddy/midi/midMessage.c b/lib/drivers/sound/mmebuddy/midi/midMessage.c index a99b6dc29ad..9e1a0ec24f6 100644 --- a/lib/drivers/sound/mmebuddy/midi/midMessage.c +++ b/lib/drivers/sound/mmebuddy/midi/midMessage.c @@ -24,11 +24,11 @@ DWORD APIENTRY midMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/lib/drivers/sound/mmebuddy/midi/modMessage.c b/lib/drivers/sound/mmebuddy/midi/modMessage.c index bde698719e4..febfca516b5 100644 --- a/lib/drivers/sound/mmebuddy/midi/modMessage.c +++ b/lib/drivers/sound/mmebuddy/midi/modMessage.c @@ -24,11 +24,11 @@ DWORD APIENTRY modMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c index 86e63773c0e..cf870540ba1 100644 --- a/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c +++ b/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c @@ -20,10 +20,10 @@ MMRESULT MmeGetLineInfo( - IN DWORD Message, - IN DWORD PrivateHandle, - IN DWORD Parameter1, - IN DWORD Parameter2) + IN UINT Message, + IN DWORD_PTR PrivateHandle, + IN DWORD_PTR Parameter1, + IN DWORD_PTR Parameter2) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -54,7 +54,7 @@ MmeGetLineInfo( MMRESULT MmeCloseMixerDevice( - IN DWORD PrivateHandle) + IN DWORD_PTR PrivateHandle) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -122,7 +122,7 @@ MmeOpenMixerDevice( } /* Store the device instance pointer in the private handle - is DWORD safe here? */ - *PrivateHandle = (DWORD) SoundDeviceInstance; + *PrivateHandle = (DWORD_PTR) SoundDeviceInstance; /* Store the additional information we were given - FIXME: Need flags! */ SetSoundDeviceInstanceMmeData(SoundDeviceInstance, @@ -151,11 +151,11 @@ MmeOpenMixerDevice( DWORD APIENTRY mxdMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; diff --git a/lib/drivers/sound/mmebuddy/mmewrap.c b/lib/drivers/sound/mmebuddy/mmewrap.c index 63f3e6f5c5a..960c4839a50 100644 --- a/lib/drivers/sound/mmebuddy/mmewrap.c +++ b/lib/drivers/sound/mmebuddy/mmewrap.c @@ -22,7 +22,7 @@ MMRESULT MmeSetState( - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN BOOL bStart) { MMRESULT Result; @@ -64,8 +64,8 @@ MmeSetState( VOID NotifyMmeClient( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, - IN DWORD Message, - IN DWORD Parameter) + IN UINT Message, + IN DWORD_PTR Parameter) { SND_ASSERT( SoundDeviceInstance ); @@ -121,10 +121,10 @@ MmeGetSoundDeviceCapabilities( MMRESULT MmeOpenWaveDevice( IN MMDEVICE_TYPE DeviceType, - IN DWORD DeviceId, + IN UINT DeviceId, IN LPWAVEOPENDESC OpenParameters, IN DWORD Flags, - OUT DWORD* PrivateHandle) + OUT DWORD_PTR* PrivateHandle) { MMRESULT Result; @@ -170,8 +170,8 @@ MmeOpenWaveDevice( return TranslateInternalMmResult(Result); } - /* Store the device instance pointer in the private handle - is DWORD safe here? */ - *PrivateHandle = (DWORD) SoundDeviceInstance; + /* Store the device instance pointer in the private handle */ + *PrivateHandle = (DWORD_PTR)SoundDeviceInstance; /* Store the additional information we were given - FIXME: Need flags! */ SetSoundDeviceInstanceMmeData(SoundDeviceInstance, @@ -195,7 +195,7 @@ MmeOpenWaveDevice( MMRESULT MmeCloseDevice( - IN DWORD PrivateHandle) + IN DWORD_PTR PrivateHandle) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -235,7 +235,7 @@ MmeCloseDevice( MMRESULT MmeResetWavePlayback( - IN DWORD PrivateHandle) + IN DWORD_PTR PrivateHandle) { PSOUND_DEVICE_INSTANCE SoundDeviceInstance; @@ -284,7 +284,7 @@ MMRESULT MmeGetPosition( IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, - IN DWORD PrivateHandle, + IN DWORD_PTR PrivateHandle, IN MMTIME* Time, IN DWORD Size) { diff --git a/lib/drivers/sound/mmebuddy/wave/header.c b/lib/drivers/sound/mmebuddy/wave/header.c index bf5b80b6496..b4d7fdcf119 100644 --- a/lib/drivers/sound/mmebuddy/wave/header.c +++ b/lib/drivers/sound/mmebuddy/wave/header.c @@ -359,5 +359,5 @@ CompleteWaveHeader( /* Safe to do this without thread protection, as we're done with the header */ NotifyMmeClient(SoundDeviceInstance, DeviceType == WAVE_OUT_DEVICE_TYPE ? WOM_DONE : WIM_DATA, - (DWORD) Header); + (DWORD_PTR)Header); } diff --git a/lib/drivers/sound/mmebuddy/wave/widMessage.c b/lib/drivers/sound/mmebuddy/wave/widMessage.c index ce1e4dffce3..47825aeccd9 100644 --- a/lib/drivers/sound/mmebuddy/wave/widMessage.c +++ b/lib/drivers/sound/mmebuddy/wave/widMessage.c @@ -25,11 +25,11 @@ DWORD APIENTRY widMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; @@ -72,7 +72,7 @@ widMessage( DeviceId, (LPWAVEOPENDESC) Parameter1, Parameter2, - (DWORD*) PrivateHandle); + (DWORD_PTR*) PrivateHandle); break; } diff --git a/lib/drivers/sound/mmebuddy/wave/wodMessage.c b/lib/drivers/sound/mmebuddy/wave/wodMessage.c index de579f32200..70bd6b70d05 100644 --- a/lib/drivers/sound/mmebuddy/wave/wodMessage.c +++ b/lib/drivers/sound/mmebuddy/wave/wodMessage.c @@ -34,11 +34,11 @@ MMRESULT HelloWorld(PSOUND_DEVICE_INSTANCE Instance, PVOID String) DWORD APIENTRY wodMessage( - DWORD DeviceId, - DWORD Message, - DWORD PrivateHandle, - DWORD Parameter1, - DWORD Parameter2) + UINT DeviceId, + UINT Message, + DWORD_PTR PrivateHandle, + DWORD_PTR Parameter1, + DWORD_PTR Parameter2) { MMRESULT Result = MMSYSERR_NOTSUPPORTED; @@ -69,7 +69,7 @@ wodMessage( DeviceId, (LPWAVEOPENDESC) Parameter1, Parameter2, - (DWORD*) PrivateHandle); + (DWORD_PTR*)PrivateHandle); break; } diff --git a/lib/drivers/sound/mment4/control.c b/lib/drivers/sound/mment4/control.c index 87a9a4f9d50..077620bf7ec 100644 --- a/lib/drivers/sound/mment4/control.c +++ b/lib/drivers/sound/mment4/control.c @@ -101,7 +101,7 @@ GetNt4SoundDeviceCapabilities( Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); - if ( ! MMSUCCESS(Result) ); + if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); /* Choose the appropriate IOCTL */ @@ -117,6 +117,7 @@ GetNt4SoundDeviceCapabilities( { /* FIXME - need to support AUX and mixer devices */ SND_ASSERT( FALSE ); + IoCtl = 0; } /* Get the capabilities information from the driver */ diff --git a/lib/rtl/actctx.c b/lib/rtl/actctx.c index 7960f587490..40883a8ff22 100644 --- a/lib/rtl/actctx.c +++ b/lib/rtl/actctx.c @@ -1578,6 +1578,7 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident { /* let's assume utf-8 for now */ int len; + WCHAR *new_buff; _SEH2_TRY { @@ -1591,20 +1592,19 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident _SEH2_END; DPRINT("len = %x\n", len); - WCHAR *new_buff; if (len == -1) { DPRINT1( "utf-8 conversion failed\n" ); return STATUS_SXS_CANT_GEN_ACTCTX; } - if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR) ))) + if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len))) return STATUS_NO_MEMORY; - mbstowcs( new_buff, buffer, len); + mbstowcs( new_buff, buffer, size); xmlbuf.ptr = new_buff; - DPRINT("Buffer %S\n", new_buff); - xmlbuf.end = xmlbuf.ptr + len; + + xmlbuf.end = xmlbuf.ptr + len / sizeof(WCHAR); status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf ); RtlFreeHeap( RtlGetProcessHeap(), 0, new_buff ); diff --git a/lib/rtl/process.c b/lib/rtl/process.c index b8585b0fe6f..ae91e2423f7 100644 --- a/lib/rtl/process.c +++ b/lib/rtl/process.c @@ -5,6 +5,7 @@ * PURPOSE: Process functions * PROGRAMMER: Alex Ionescu (alex@relsoft.net) * Ariadne (ariadne@xs4all.nl) + * Eric Kohl */ /* INCLUDES ****************************************************************/ @@ -42,7 +43,7 @@ RtlpMapFile(PUNICODE_STRING ImageFileName, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to read image file from disk\n"); - return(Status); + return Status; } /* Now create a section for this image */ @@ -93,7 +94,7 @@ RtlpInitEnvironment(HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to reserve 1MB of space \n"); - return(Status); + return Status; } } @@ -117,7 +118,7 @@ RtlpInitEnvironment(HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to allocate Environment Block\n"); - return(Status); + return Status; } /* Write the Environment Block */ @@ -143,7 +144,7 @@ RtlpInitEnvironment(HANDLE ProcessHandle, if (!NT_SUCCESS(Status)) { DPRINT1("Failed to allocate Parameter Block\n"); - return(Status); + return Status; } /* Write the Parameter Block */ @@ -244,7 +245,7 @@ RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, { DPRINT1("Could not create Kernel Process Object\n"); ZwClose(hSection); - return(Status); + return Status; } /* Get some information on the image */ @@ -258,7 +259,7 @@ RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, DPRINT1("Could not query Section Info\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); - return(Status); + return Status; } /* Get some information about the process */ @@ -272,7 +273,7 @@ RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, DPRINT1("Could not query Process Info\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); - return(Status); + return Status; } /* Create Process Environment */ @@ -311,22 +312,21 @@ PVOID NTAPI RtlEncodePointer(IN PVOID Pointer) { - ULONG Cookie; - NTSTATUS Status; + ULONG Cookie; + NTSTATUS Status; - Status = ZwQueryInformationProcess(NtCurrentProcess(), - ProcessCookie, - &Cookie, - sizeof(Cookie), - NULL); + Status = ZwQueryInformationProcess(NtCurrentProcess(), + ProcessCookie, + &Cookie, + sizeof(Cookie), + NULL); + if(!NT_SUCCESS(Status)) + { + DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status); + return Pointer; + } - if(!NT_SUCCESS(Status)) - { - DPRINT1("Failed to receive the process cookie! Status: 0x%lx\n", Status); - return Pointer; - } - - return (PVOID)((ULONG_PTR)Pointer ^ Cookie); + return (PVOID)((ULONG_PTR)Pointer ^ Cookie); } /* @@ -336,33 +336,59 @@ PVOID NTAPI RtlDecodePointer(IN PVOID Pointer) { - return RtlEncodePointer(Pointer); + return RtlEncodePointer(Pointer); } /* - * @unimplemented + * @implemented */ PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer) { - UNIMPLEMENTED; - return NULL; + return (PVOID)((ULONG_PTR)Pointer ^ SharedUserData->Cookie); } /* - * @unimplemented + * @implemented + * + * NOTES: + * Implementation based on the documentation from: + * http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm */ -NTSYSAPI -VOID +NTSTATUS NTAPI -RtlSetProcessIsCritical( - IN BOOLEAN NewValue, - OUT PBOOLEAN OldValue OPTIONAL, - IN BOOLEAN IsWinlogon) +RtlSetProcessIsCritical(IN BOOLEAN NewValue, + OUT PBOOLEAN OldValue OPTIONAL, + IN BOOLEAN NeedBreaks) { - //TODO - UNIMPLEMENTED; + ULONG BreakOnTermination = FALSE; + + if (OldValue) + *OldValue = FALSE; + + /* Fail, if the critical breaks flag is required but is not set */ + if (NeedBreaks == TRUE && + !(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS)) + return STATUS_UNSUCCESSFUL; + + if (OldValue) + { + /* Query and return the old break on termination flag for the process */ + ZwQueryInformationProcess(NtCurrentProcess(), + ProcessBreakOnTermination, + &BreakOnTermination, + sizeof(ULONG), + NULL); + *OldValue = (BOOLEAN)BreakOnTermination; + } + + /* Set the break on termination flag for the process */ + BreakOnTermination = NewValue; + return ZwSetInformationProcess(NtCurrentProcess(), + ProcessBreakOnTermination, + &BreakOnTermination, + sizeof(ULONG)); } ULONG diff --git a/lib/sdk/crt/math/i386/ldexp.c b/lib/sdk/crt/math/i386/ldexp.c index b240275ef95..327e72a27b8 100644 --- a/lib/sdk/crt/math/i386/ldexp.c +++ b/lib/sdk/crt/math/i386/ldexp.c @@ -21,24 +21,32 @@ #include -double ldexp (double __x, int __y); - -double ldexp (double __x, int __y) +double ldexp (double value, int exp) { - register double __val; + register double result; #ifdef __GNUC__ - __asm __volatile__ - ("fscale" - : "=t" (__val) : "0" (__x), "u" ((double) __y)); +#if defined(__clang__) + asm ("fild %[exp]\n" + "fscale\n" + "fstp %%st(1)\n" + : [result] "=t" (result) + : [value] "0" (value), [exp] "m" (exp)); #else - register double __dy = (double)__y; + asm ("fscale" + : "=t" (result) + : "0" (value), "u" ((double)exp) + : "1"); +#endif +#else /* !__GNUC__ */ + register double __dy = (double)exp; __asm { fld __dy - fld __x + fld value fscale - fstp __val + fstp result } -#endif /*__GNUC__*/ - return __val; +#endif /* !__GNUC__ */ + return result; } + diff --git a/lib/sdk/crt/misc/getargs.c b/lib/sdk/crt/misc/getargs.c index 1bdb409ab46..18672e6bd44 100644 --- a/lib/sdk/crt/misc/getargs.c +++ b/lib/sdk/crt/misc/getargs.c @@ -22,7 +22,7 @@ int __argc = 0; extern wchar_t **__winitenv; -char* strndup(char* name, size_t len) +char* strndup(char const* name, size_t len) { char *s = malloc(len + 1); if (s != NULL) diff --git a/lib/sdk/crt/process/_system.c b/lib/sdk/crt/process/_system.c index f6173db03c6..3f9712b5737 100644 --- a/lib/sdk/crt/process/_system.c +++ b/lib/sdk/crt/process/_system.c @@ -35,11 +35,14 @@ int system(const char *command) // system should return 0 if command is null and the shell is found if (command == NULL) { - if (szComSpec == NULL) - return 0; - else - return -1; - } + if (szComSpec == NULL) + return 0; + else + return 1; + } + + if (szComSpec == NULL) + return -1; // should return 127 or 0 ( MS ) if the shell is not found // __set_errno(ENOENT); diff --git a/lib/sdk/crt/signal/signal.c b/lib/sdk/crt/signal/signal.c index 6cfe3f64b5a..5dd6381c53d 100644 --- a/lib/sdk/crt/signal/signal.c +++ b/lib/sdk/crt/signal/signal.c @@ -42,7 +42,7 @@ __p_sig_fn_t signal(int sig, __p_sig_fn_t func) } // check with IsBadCodePtr - if ( func < (__p_sig_fn_t)4096 && func != SIG_DFL && func != SIG_IGN) + if ( (uintptr_t)func < 4096 && func != SIG_DFL && func != SIG_IGN) { __set_errno(EINVAL); return SIG_ERR; diff --git a/lib/sdk/crt/string/mbstowcs_nt.c b/lib/sdk/crt/string/mbstowcs_nt.c index 8ab1edd23e3..4b613368c3e 100644 --- a/lib/sdk/crt/string/mbstowcs_nt.c +++ b/lib/sdk/crt/string/mbstowcs_nt.c @@ -47,7 +47,7 @@ size_t mbstowcs (wchar_t *wcstr, const char *mbstr, size_t count) } Status = RtlMultiByteToUnicodeN (wcstr, - count, + count * sizeof(WCHAR), &Size, mbstr, Length); diff --git a/lib/sdk/crt/string/strset.c b/lib/sdk/crt/string/strset.c index e6c422d4f9c..29a72121197 100644 --- a/lib/sdk/crt/string/strset.c +++ b/lib/sdk/crt/string/strset.c @@ -1,14 +1,14 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries - * FILE: lib/crt/?????? - * PURPOSE: Unknown + * FILE: lib/crt/strset.c + * PURPOSE: Implementation of _strnset and _strset * PROGRAMER: Unknown * UPDATE HISTORY: * 25/11/05: Added license header */ -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__clang__) #define __int64 long long #endif diff --git a/media/fonts/DejaVuSans-Bold.ttf b/media/fonts/DejaVuSans-Bold.ttf index ec1a2ebaf24..7b29accc131 100644 Binary files a/media/fonts/DejaVuSans-Bold.ttf and b/media/fonts/DejaVuSans-Bold.ttf differ diff --git a/media/fonts/DejaVuSans-BoldOblique.ttf b/media/fonts/DejaVuSans-BoldOblique.ttf index 1a5576460d5..b5440d95e79 100644 Binary files a/media/fonts/DejaVuSans-BoldOblique.ttf and b/media/fonts/DejaVuSans-BoldOblique.ttf differ diff --git a/media/fonts/DejaVuSans-Oblique.ttf b/media/fonts/DejaVuSans-Oblique.ttf index becc5499273..e233295c464 100644 Binary files a/media/fonts/DejaVuSans-Oblique.ttf and b/media/fonts/DejaVuSans-Oblique.ttf differ diff --git a/media/fonts/DejaVuSans.ttf b/media/fonts/DejaVuSans.ttf index c1b19d87059..a36615b2081 100644 Binary files a/media/fonts/DejaVuSans.ttf and b/media/fonts/DejaVuSans.ttf differ diff --git a/media/fonts/DejaVuSansMono-Bold.ttf b/media/fonts/DejaVuSansMono-Bold.ttf index 32a8695f70c..98bb6f62e21 100644 Binary files a/media/fonts/DejaVuSansMono-Bold.ttf and b/media/fonts/DejaVuSansMono-Bold.ttf differ diff --git a/media/fonts/DejaVuSansMono-BoldOblique.ttf b/media/fonts/DejaVuSansMono-BoldOblique.ttf index 5e2ee0339c9..42bbcdee974 100644 Binary files a/media/fonts/DejaVuSansMono-BoldOblique.ttf and b/media/fonts/DejaVuSansMono-BoldOblique.ttf differ diff --git a/media/fonts/DejaVuSansMono-Oblique.ttf b/media/fonts/DejaVuSansMono-Oblique.ttf index 9789ea057c5..d6ab52298c1 100644 Binary files a/media/fonts/DejaVuSansMono-Oblique.ttf and b/media/fonts/DejaVuSansMono-Oblique.ttf differ diff --git a/media/fonts/DejaVuSansMono.ttf b/media/fonts/DejaVuSansMono.ttf index 6bc854ddae9..b464c52ade0 100644 Binary files a/media/fonts/DejaVuSansMono.ttf and b/media/fonts/DejaVuSansMono.ttf differ diff --git a/media/fonts/DejaVuSerif-Bold.ttf b/media/fonts/DejaVuSerif-Bold.ttf index aee1ae626fe..8c53b1a1124 100644 Binary files a/media/fonts/DejaVuSerif-Bold.ttf and b/media/fonts/DejaVuSerif-Bold.ttf differ diff --git a/media/fonts/DejaVuSerif-BoldItalic.ttf b/media/fonts/DejaVuSerif-BoldItalic.ttf index 1b55e27214e..688c2b70f71 100644 Binary files a/media/fonts/DejaVuSerif-BoldItalic.ttf and b/media/fonts/DejaVuSerif-BoldItalic.ttf differ diff --git a/media/fonts/DejaVuSerif-Italic.ttf b/media/fonts/DejaVuSerif-Italic.ttf index 4464868f753..b2ed04a1230 100644 Binary files a/media/fonts/DejaVuSerif-Italic.ttf and b/media/fonts/DejaVuSerif-Italic.ttf differ diff --git a/media/fonts/DejaVuSerif.ttf b/media/fonts/DejaVuSerif.ttf index 1f2c94fa01b..19eba334572 100644 Binary files a/media/fonts/DejaVuSerif.ttf and b/media/fonts/DejaVuSerif.ttf differ diff --git a/media/fonts/LiberationMono-Bold.ttf b/media/fonts/LiberationMono-Bold.ttf index 95de75300f7..c11a84dba71 100644 Binary files a/media/fonts/LiberationMono-Bold.ttf and b/media/fonts/LiberationMono-Bold.ttf differ diff --git a/media/fonts/LiberationMono-BoldItalic.ttf b/media/fonts/LiberationMono-BoldItalic.ttf index 11ec3e7793a..ef185adaabc 100644 Binary files a/media/fonts/LiberationMono-BoldItalic.ttf and b/media/fonts/LiberationMono-BoldItalic.ttf differ diff --git a/media/fonts/LiberationMono-Italic.ttf b/media/fonts/LiberationMono-Italic.ttf index 08f55d6367d..ce27ca7c250 100644 Binary files a/media/fonts/LiberationMono-Italic.ttf and b/media/fonts/LiberationMono-Italic.ttf differ diff --git a/media/fonts/LiberationMono-Regular.ttf b/media/fonts/LiberationMono-Regular.ttf index e3024a09d8c..a74d2277682 100644 Binary files a/media/fonts/LiberationMono-Regular.ttf and b/media/fonts/LiberationMono-Regular.ttf differ diff --git a/media/fonts/LiberationSans-Bold.ttf b/media/fonts/LiberationSans-Bold.ttf index 53200d956c9..f9ad862c37e 100644 Binary files a/media/fonts/LiberationSans-Bold.ttf and b/media/fonts/LiberationSans-Bold.ttf differ diff --git a/media/fonts/LiberationSans-BoldItalic.ttf b/media/fonts/LiberationSans-BoldItalic.ttf index d06deca60d1..b7b5b5b4476 100644 Binary files a/media/fonts/LiberationSans-BoldItalic.ttf and b/media/fonts/LiberationSans-BoldItalic.ttf differ diff --git a/media/fonts/LiberationSans-Italic.ttf b/media/fonts/LiberationSans-Italic.ttf index 07275adf6c1..b23254f6f41 100644 Binary files a/media/fonts/LiberationSans-Italic.ttf and b/media/fonts/LiberationSans-Italic.ttf differ diff --git a/media/fonts/LiberationSans-Regular.ttf b/media/fonts/LiberationSans-Regular.ttf index 09fac2ff94a..9d557bbb7b8 100644 Binary files a/media/fonts/LiberationSans-Regular.ttf and b/media/fonts/LiberationSans-Regular.ttf differ diff --git a/media/fonts/LiberationSerif-Bold.ttf b/media/fonts/LiberationSerif-Bold.ttf index 3a4ab92ac48..f45b38205d3 100644 Binary files a/media/fonts/LiberationSerif-Bold.ttf and b/media/fonts/LiberationSerif-Bold.ttf differ diff --git a/media/fonts/LiberationSerif-BoldItalic.ttf b/media/fonts/LiberationSerif-BoldItalic.ttf index dc75de89c0f..b0ca8c6dc76 100644 Binary files a/media/fonts/LiberationSerif-BoldItalic.ttf and b/media/fonts/LiberationSerif-BoldItalic.ttf differ diff --git a/media/fonts/LiberationSerif-Italic.ttf b/media/fonts/LiberationSerif-Italic.ttf index d92b5e39292..006db7e16e1 100644 Binary files a/media/fonts/LiberationSerif-Italic.ttf and b/media/fonts/LiberationSerif-Italic.ttf differ diff --git a/media/fonts/LiberationSerif-Regular.ttf b/media/fonts/LiberationSerif-Regular.ttf index d100691a255..394c75c1df9 100644 Binary files a/media/fonts/LiberationSerif-Regular.ttf and b/media/fonts/LiberationSerif-Regular.ttf differ diff --git a/ntoskrnl/config/cmkcbncb.c b/ntoskrnl/config/cmkcbncb.c index a26de07cf1b..a123a3cee56 100644 --- a/ntoskrnl/config/cmkcbncb.c +++ b/ntoskrnl/config/cmkcbncb.c @@ -234,7 +234,9 @@ CmpGetNameControlBlock(IN PUNICODE_STRING NodeName) if (Found) { /* Reference it */ + ASSERT(Ncb->RefCount != 0xFFFF); Ncb->RefCount++; + break; } } @@ -320,6 +322,7 @@ CmpDereferenceNameControlBlockWithLock(IN PCM_NAME_CONTROL_BLOCK Ncb) CmpAcquireNcbLockExclusiveByKey(ConvKey); /* Decrease the reference count */ + ASSERT(Ncb->RefCount >= 1); if (!(--Ncb->RefCount)) { /* Find the NCB in the table */ @@ -579,7 +582,7 @@ CmpDereferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb) NewRefCount = OldRefCount - 1; /* Check if we still have references */ - if( (NewRefCount & 0xFFFF) > 0) + if ((NewRefCount & 0xFFFF) > 0) { /* Do the dereference */ if (InterlockedCompareExchange((PLONG)&Kcb->RefCount, diff --git a/ntoskrnl/include/internal/amd64/ke.h b/ntoskrnl/include/internal/amd64/ke.h index f661b203b28..9b5340ce6e9 100644 --- a/ntoskrnl/include/internal/amd64/ke.h +++ b/ntoskrnl/include/internal/amd64/ke.h @@ -163,6 +163,52 @@ KiRundownThread(IN PKTHREAD Thread) #endif } +/* Registers an interrupt handler with an IDT vector */ +FORCEINLINE +VOID +KeRegisterInterruptHandler(IN ULONG Vector, + IN PVOID Handler) +{ + UCHAR Entry; + PKIDTENTRY64 Idt; + + /* Get the entry from the HAL */ + Entry = HalVectorToIDTEntry(Vector); + + /* Now set the data */ + Idt = &KeGetPcr()->IdtBase[Entry]; + Idt->OffsetLow = (ULONG_PTR)Handler & 0xffff; + Idt->OffsetMiddle = ((ULONG_PTR)Handler >> 16) & 0xffff; + Idt->OffsetHigh = (ULONG_PTR)Handler >> 32; + Idt->Selector = KGDT64_R0_CODE; + Idt->IstIndex = 0; + Idt->Type = 0x0e; + Idt->Dpl = 0; + Idt->Present = 1; + Idt->Reserved0 = 0; + Idt->Reserved1 = 0; +} + +/* Returns the registered interrupt handler for a given IDT vector */ +FORCEINLINE +PVOID +KeQueryInterruptHandler(IN ULONG Vector) +{ + UCHAR Entry; + PKIDTENTRY64 Idt; + + /* Get the entry from the HAL */ + Entry = HalVectorToIDTEntry(Vector); + + /* Get the IDT entry */ + Idt = &KeGetPcr()->IdtBase[Entry]; + + /* Return the address */ + return (PVOID)((ULONG64)Idt->OffsetHigh << 32 | + (ULONG64)Idt->OffsetMiddle << 16 | + (ULONG64)Idt->OffsetLow); +} + VOID FORCEINLINE KiEndInterrupt(IN KIRQL Irql, diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 8b50570ae5e..bc5f293e482 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -780,8 +780,7 @@ KiSwitchToBootStack(IN ULONG_PTR InitialStack) VOID NTAPI KiSystemStartupBootStack(VOID); __asm { - mov ecx, InitialStack - mov esp, ecx + mov esp, InitialStack sub esp, (NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH) push (CR0_EM | CR0_TS | CR0_MP) jmp KiSystemStartupBootStack @@ -791,6 +790,30 @@ KiSwitchToBootStack(IN ULONG_PTR InitialStack) #endif } +// +// Emits the iret instruction for C code +// +DECLSPEC_NORETURN +VOID +FORCEINLINE +KiIret(VOID) +{ +#if defined(__GNUC__) + __asm__ __volatile__ + ( + "iret\n" + ); +#elif defined(_MSC_VER) + __asm + { + iret + } +#else +#error Unsupported compiler +#endif + UNREACHABLE; +} + // // Normally this is done by the HAL, but on x86 as an optimization, the kernel // initiates the end by calling back into the HAL and exiting the trap here. diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 9398ef1d7ff..326f19c4dc6 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -496,9 +496,7 @@ typedef struct _DEVICETREE_TRAVERSE_CONTEXT // ULONG NTAPI -IopCalculateResourceListSize( - IN PCM_RESOURCE_LIST ResourceList -); +PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList); NTSTATUS NTAPI diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index db7003d1438..d8c61786f3f 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -364,7 +364,7 @@ typedef struct _MMPFN } u4; } MMPFN, *PMMPFN; -extern PMMPFN MmPfnDatabase[2]; +extern PMMPFN MmPfnDatabase; typedef struct _MMPFNLIST { @@ -1095,7 +1095,7 @@ MiGetPfnEntry(IN PFN_TYPE Pfn) if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, Pfn))) return NULL; /* Get the entry */ - Page = &MmPfnDatabase[0][Pfn]; + Page = &MmPfnDatabase[Pfn]; /* Return it */ return Page; @@ -1108,7 +1108,7 @@ MiGetPfnEntryIndex(IN PMMPFN Pfn1) // // This will return the Page Frame Number (PFN) from the MMPFN // - return Pfn1 - MmPfnDatabase[0]; + return Pfn1 - MmPfnDatabase; } PFN_TYPE diff --git a/ntoskrnl/include/internal/ps_i.h b/ntoskrnl/include/internal/ps_i.h index 75a4994f24a..13251f8e901 100644 --- a/ntoskrnl/include/internal/ps_i.h +++ b/ntoskrnl/include/internal/ps_i.h @@ -249,9 +249,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = /* ProcessBreakOnTermination */ IQS_SAME ( - UCHAR, - UCHAR, - 0 + ULONG, + ULONG, + ICIF_QUERY | ICIF_SET ), /* ProcessDebugObjectHandle */ diff --git a/ntoskrnl/include/internal/trap_x.h b/ntoskrnl/include/internal/trap_x.h index 3da69917d70..0d61dd6f78b 100644 --- a/ntoskrnl/include/internal/trap_x.h +++ b/ntoskrnl/include/internal/trap_x.h @@ -8,7 +8,7 @@ #pragma once -//#define TRAP_DEBUG 1 +#define TRAP_DEBUG 0 // // Unreachable code hint for GCC 4.5.x, older GCC versions, and MSVC @@ -81,7 +81,7 @@ KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame) DbgPrint("V86Gs: %x\n", TrapFrame->V86Gs); } -#ifdef TRAP_DEBUG +#if TRAP_DEBUG VOID FORCEINLINE KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame) @@ -168,7 +168,7 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall, 0, 0); } -#if 0 + /* Make sure we're not attached and that APCs are not disabled */ if ((KeGetCurrentThread()->ApcStateIndex != CurrentApcEnvironment) || (KeGetCurrentThread()->CombinedApcDisable != 0)) @@ -180,7 +180,6 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall, KeGetCurrentThread()->CombinedApcDisable, 0); } -#endif } } #else @@ -200,9 +199,11 @@ DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame); DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame); typedef +DECLSPEC_NORETURN VOID -(FASTCALL -*PFAST_SYSTEM_CALL_EXIT)(IN PKTRAP_FRAME TrapFrame); +(FASTCALL *PFAST_SYSTEM_CALL_EXIT)( + IN PKTRAP_FRAME TrapFrame +); extern PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler; @@ -222,7 +223,7 @@ KiExitV86Trap(IN PKTRAP_FRAME TrapFrame) while (TRUE) { /* Return if this isn't V86 mode anymore */ - if (!(TrapFrame->EFlags & EFLAGS_V86_MASK)) KiEoiHelper(TrapFrame);; + if (!(TrapFrame->EFlags & EFLAGS_V86_MASK)) KiEoiHelper(TrapFrame); /* Turn off the alerted state for kernel mode */ Thread->Alerted[KernelMode] = FALSE; diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c index 1ab54458526..7dcb0354ea1 100644 --- a/ntoskrnl/io/iomgr/driver.c +++ b/ntoskrnl/io/iomgr/driver.c @@ -1171,17 +1171,18 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) 0, (PVOID*)&DriverObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Can't locate driver object for %wZ\n", &ObjectName); + ExFreePool(ObjectName.Buffer); + return Status; + } + /* * Free the buffer for driver object name */ ExFreePool(ObjectName.Buffer); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Can't locate driver object for %wZ\n", &ObjectName); - return Status; - } - /* Check that driver is not already unloading */ if (DriverObject->Flags & DRVO_UNLOAD_INVOKED) { @@ -1555,11 +1556,14 @@ try_again: * Doing so is illegal; drivers shouldn't touch entry points they * do not implement. */ - ASSERT(DriverObject->MajorFunction[i] != NULL); /* Check if it did so anyway */ - if (!DriverObject->MajorFunction[i]) + if (!DriverObject->MajorFunction[i]) { + /* Print a warning in the debug log */ + DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%d] to NULL!\n", + &DriverObject->DriverName, i); + /* Fix it up */ DriverObject->MajorFunction[i] = IopInvalidDeviceRequest; } diff --git a/ntoskrnl/io/iomgr/irp.c b/ntoskrnl/io/iomgr/irp.c index 0863f58907b..d7e4ed2741f 100644 --- a/ntoskrnl/io/iomgr/irp.c +++ b/ntoskrnl/io/iomgr/irp.c @@ -1217,15 +1217,22 @@ IofCompleteRequest(IN PIRP Irp, ErrorCode = PtrToUlong(LastStackPtr->Parameters.Others.Argument4); } - /* Get the Current Stack */ - StackPtr = IoGetCurrentIrpStackLocation(Irp); - - /* Loop the Stacks and complete the IRPs */ - do + /* + * Start the loop with the current stack and point the IRP to the next stack + * and then keep incrementing the stack as we loop through. The IRP should + * always point to the next stack location w.r.t the one currently being + * analyzed, so completion routine code will see the appropriate value. + * Because of this, we must loop until the current stack location is +1 of + * the stack count, because when StackPtr is at the end, CurrentLocation is +1. + */ + for (StackPtr = IoGetCurrentIrpStackLocation(Irp), + Irp->CurrentLocation++, + Irp->Tail.Overlay.CurrentStackLocation++; + Irp->CurrentLocation <= (Irp->StackCount + 1); + StackPtr++, + Irp->CurrentLocation++, + Irp->Tail.Overlay.CurrentStackLocation++) { - /* Skip current stack location */ - IoSkipCurrentIrpStackLocation(Irp); - /* Set Pending Returned */ Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED; @@ -1287,10 +1294,7 @@ IofCompleteRequest(IN PIRP Irp, /* Clear the stack location */ IopClearStackLocation(StackPtr); } - - /* Move pointer to next stack location */ - StackPtr++; - } while (Irp->CurrentLocation <= Irp->StackCount); + } /* Check if the IRP is an associated IRP */ if (Irp->Flags & IRP_ASSOCIATED_IRP) diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 645b837de81..9d130eca9df 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -948,7 +948,7 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, 0, REG_RESOURCE_LIST, DeviceNode->BootResources, - IopCalculateResourceListSize(DeviceNode->BootResources)); + PnpDetermineResourceListSize(DeviceNode->BootResources)); } } @@ -3003,6 +3003,241 @@ PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject) /* PUBLIC FUNCTIONS **********************************************************/ +NTSTATUS +NTAPI +PnpBusTypeGuidGet(IN USHORT Index, + IN LPGUID BusTypeGuid) +{ + NTSTATUS Status = STATUS_SUCCESS; + + /* Acquire the lock */ + ExAcquireFastMutex(&PnpBusTypeGuidList->Lock); + + /* Validate size */ + if (Index < PnpBusTypeGuidList->GuidCount) + { + /* Copy the data */ + RtlCopyMemory(BusTypeGuid, &PnpBusTypeGuidList->Guids[Index], sizeof(GUID)); + } + else + { + /* Failure path */ + Status = STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* Release lock and return status */ + ExReleaseFastMutex(&PnpBusTypeGuidList->Lock); + return Index; +} + +NTSTATUS +NTAPI +PpIrpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, + OUT PDEVICE_CAPABILITIES DeviceCaps) +{ + PAGED_CODE(); + PVOID Dummy; + IO_STACK_LOCATION Stack; + + /* Set up the Header */ + RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES)); + DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES); + DeviceCaps->Version = 1; + DeviceCaps->Address = -1; + DeviceCaps->UINumber = -1; + + /* Set up the Stack */ + RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION)); + Stack.MajorFunction = IRP_MJ_PNP; + Stack.MinorFunction = IRP_MN_QUERY_CAPABILITIES; + Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps; + + /* Send the IRP */ + return IopSynchronousCall(DeviceObject, &Stack, &Dummy); +} + +NTSTATUS +NTAPI +PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject, + IN PHANDLE DeviceInstanceHandle, + IN ACCESS_MASK DesiredAccess) +{ + NTSTATUS Status; + HANDLE KeyHandle; + PDEVICE_NODE DeviceNode; + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM"); + PAGED_CODE(); + + /* Open the enum key */ + Status = IopOpenRegistryKeyEx(&KeyHandle, + NULL, + &KeyName, + KEY_READ); + if (!NT_SUCCESS(Status)) return Status; + + /* Make sure we have an instance path */ + DeviceNode = IopGetDeviceNode(DeviceObject); + if ((DeviceNode) && (DeviceNode->InstancePath.Length)) + { + /* Get the instance key */ + Status = IopOpenRegistryKeyEx(DeviceInstanceHandle, + KeyHandle, + &DeviceNode->InstancePath, + DesiredAccess); + } + else + { + /* Fail */ + Status = STATUS_INVALID_DEVICE_REQUEST; + } + + /* Close the handle and return status */ + ZwClose(KeyHandle); + return Status; +} + +ULONG +NTAPI +PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList) +{ + ULONG FinalSize, PartialSize, EntrySize, i, j; + PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; + + /* If we don't have one, that's easy */ + if (!ResourceList) return 0; + + /* Start with the minimum size possible */ + FinalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List); + + /* Loop each full descriptor */ + FullDescriptor = ResourceList->List; + for (i = 0; i < ResourceList->Count; i++) + { + /* Start with the minimum size possible */ + PartialSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) + + FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors); + + /* Loop each partial descriptor */ + PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors; + for (j = 0; j < FullDescriptor->PartialResourceList.Count; j++) + { + /* Start with the minimum size possible */ + EntrySize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + + /* Check if there is extra data */ + if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific) + { + /* Add that data */ + EntrySize += PartialDescriptor->u.DeviceSpecificData.DataSize; + } + + /* The size of partial descriptors is bigger */ + PartialSize += EntrySize; + + /* Go to the next partial descriptor */ + PartialDescriptor = (PVOID)((ULONG_PTR)PartialDescriptor + EntrySize); + } + + /* The size of full descriptors is bigger */ + FinalSize += PartialSize; + + /* Go to the next full descriptor */ + FullDescriptor = (PVOID)((ULONG_PTR)FullDescriptor + PartialSize); + } + + /* Return the final size */ + return FinalSize; +} + +NTSTATUS +NTAPI +PiGetDeviceRegistryProperty(IN PDEVICE_OBJECT DeviceObject, + IN ULONG ValueType, + IN PWSTR ValueName, + IN PWSTR KeyName, + OUT PVOID Buffer, + IN PULONG BufferLength) +{ + NTSTATUS Status; + HANDLE KeyHandle, SubHandle; + UNICODE_STRING KeyString; + PKEY_VALUE_FULL_INFORMATION KeyValueInfo = NULL; + ULONG Length; + PAGED_CODE(); + + /* Find the instance key */ + Status = PnpDeviceObjectToDeviceInstance(DeviceObject, &KeyHandle, KEY_READ); + if (NT_SUCCESS(Status)) + { + /* Check for name given by caller */ + if (KeyName) + { + /* Open this key */ + RtlInitUnicodeString(&KeyString, KeyName); + Status = IopOpenRegistryKeyEx(&SubHandle, + KeyHandle, + &KeyString, + KEY_READ); + if (NT_SUCCESS(Status)) + { + /* And use this handle instead */ + ZwClose(KeyHandle); + KeyHandle = SubHandle; + } + } + + /* Check if sub-key handle succeeded (or no-op if no key name given) */ + if (NT_SUCCESS(Status)) + { + /* Now get the size of the property */ + Status = IopGetRegistryValue(KeyHandle, + ValueName, + &KeyValueInfo); + } + + /* Close the key */ + ZwClose(KeyHandle); + } + + /* Fail if any of the registry operations failed */ + if (!NT_SUCCESS(Status)) return Status; + + /* Check how much data we have to copy */ + Length = KeyValueInfo->DataLength; + if (*BufferLength >= Length) + { + /* Check for a match in the value type */ + if (KeyValueInfo->Type == ValueType) + { + /* Copy the data */ + RtlCopyMemory(Buffer, + (PVOID)((ULONG_PTR)KeyValueInfo + + KeyValueInfo->DataOffset), + Length); + } + else + { + /* Invalid registry property type, fail */ + Status = STATUS_INVALID_PARAMETER_2; + } + } + else + { + /* Buffer is too small to hold data */ + Status = STATUS_BUFFER_TOO_SMALL; + } + + /* Return the required buffer length, free the buffer, and return status */ + *BufferLength = Length; + ExFreePool(KeyValueInfo); + return Status; +} + +#define PIP_RETURN_DATA(x, y) {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;} +#define PIP_REGISTRY_DATA(x, y) {ValueName = x; ValueType = y; break;} +#define PIP_UNIMPLEMENTED() {UNIMPLEMENTED; while(TRUE); break;} + /* * @implemented */ @@ -3016,281 +3251,205 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, { PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); DEVICE_CAPABILITIES DeviceCaps; - ULONG Length; + ULONG ReturnLength = 0, Length = 0, ValueType; + PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName; PVOID Data = NULL; - PWSTR Ptr; - NTSTATUS Status; + NTSTATUS Status = STATUS_BUFFER_TOO_SMALL; + GUID BusTypeGuid; POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; - ULONG RequiredLength, ObjectNameInfoLength; - DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty); + /* Assume failure */ *ResultLength = 0; - if (DeviceNode == NULL) - return STATUS_INVALID_DEVICE_REQUEST; + /* Only PDOs can call this */ + if (!DeviceNode) return STATUS_INVALID_DEVICE_REQUEST; + /* Handle all properties */ switch (DeviceProperty) { - case DevicePropertyBusNumber: - Length = sizeof(ULONG); - Data = &DeviceNode->ChildBusNumber; - break; + case DevicePropertyBusTypeGuid: - /* Complete, untested */ - case DevicePropertyBusTypeGuid: - /* Sanity check */ - if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) && - (DeviceNode->ChildBusTypeIndex < PnpBusTypeGuidList->GuidCount)) - { - /* Return the GUID */ - *ResultLength = sizeof(GUID); + /* Get the GUID from the internal cache */ + Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid); + if (!NT_SUCCESS(Status)) return Status; - /* Check if the buffer given was large enough */ - if (BufferLength < *ResultLength) + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid); + + case DevicePropertyLegacyBusType: + + /* Validate correct interface type */ + if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined) + return STATUS_OBJECT_NAME_NOT_FOUND; + + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType); + + case DevicePropertyBusNumber: + + /* Validate correct bus number */ + if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000) + return STATUS_OBJECT_NAME_NOT_FOUND; + + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber); + + case DevicePropertyEnumeratorName: + + /* Get the instance path */ + DeviceInstanceName = DeviceNode->InstancePath.Buffer; + + /* Sanity checks */ + ASSERT((BufferLength & 1) == 0); + ASSERT(DeviceInstanceName != NULL); + + /* Get the name from the path */ + EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR); + ASSERT(EnumeratorNameEnd); + + /* This is the format of the returned data */ + PIP_RETURN_DATA((EnumeratorNameEnd - DeviceInstanceName) * 2, + &DeviceNode->ChildBusNumber); + + case DevicePropertyAddress: + + /* Query the device caps */ + Status = PpIrpQueryCapabilities(DeviceObject, &DeviceCaps); + if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG)) + return STATUS_OBJECT_NAME_NOT_FOUND; + + /* This is the format of the returned data */ + PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address); + + case DevicePropertyBootConfigurationTranslated: + + /* Validate we have resources */ + if (!DeviceNode->BootResources) +// if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field { - return STATUS_BUFFER_TOO_SMALL; + /* No resources will still fake success, but with 0 bytes */ + *ResultLength = 0; + return STATUS_SUCCESS; } + + /* This is the format of the returned data */ + PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated + DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated - /* Copy the GUID */ - RtlCopyMemory(PropertyBuffer, - &(PnpBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]), - sizeof(GUID)); - return STATUS_SUCCESS; - } - else - { - return STATUS_OBJECT_NAME_NOT_FOUND; - } - break; - - case DevicePropertyLegacyBusType: - Length = sizeof(INTERFACE_TYPE); - Data = &DeviceNode->ChildInterfaceType; - break; - - case DevicePropertyAddress: - /* Query the device caps */ - Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps); - if (NT_SUCCESS(Status) && (DeviceCaps.Address != MAXULONG)) - { - /* Return length */ - *ResultLength = sizeof(ULONG); - - /* Check if the buffer given was large enough */ - if (BufferLength < *ResultLength) - { - return STATUS_BUFFER_TOO_SMALL; - } - - /* Return address */ - *(PULONG)PropertyBuffer = DeviceCaps.Address; - return STATUS_SUCCESS; - } - else - { - return STATUS_OBJECT_NAME_NOT_FOUND; - } - break; - -// case DevicePropertyUINumber: -// if (DeviceNode->CapabilityFlags == NULL) -// return STATUS_INVALID_DEVICE_REQUEST; -// Length = sizeof(ULONG); -// Data = &DeviceNode->CapabilityFlags->UINumber; -// break; - - case DevicePropertyClassName: - case DevicePropertyClassGuid: - case DevicePropertyDriverKeyName: - case DevicePropertyManufacturer: - case DevicePropertyFriendlyName: - case DevicePropertyHardwareID: - case DevicePropertyCompatibleIDs: - case DevicePropertyDeviceDescription: - case DevicePropertyLocationInformation: - case DevicePropertyUINumber: - { - LPCWSTR RegistryPropertyName; - UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT); - UNICODE_STRING ValueName; - KEY_VALUE_PARTIAL_INFORMATION *ValueInformation; - ULONG ValueInformationLength; - HANDLE KeyHandle, EnumRootHandle; - NTSTATUS Status; - - switch (DeviceProperty) - { - case DevicePropertyClassName: - RegistryPropertyName = L"Class"; break; - case DevicePropertyClassGuid: - RegistryPropertyName = L"ClassGuid"; break; - case DevicePropertyDriverKeyName: - RegistryPropertyName = L"Driver"; break; - case DevicePropertyManufacturer: - RegistryPropertyName = L"Mfg"; break; - case DevicePropertyFriendlyName: - RegistryPropertyName = L"FriendlyName"; break; - case DevicePropertyHardwareID: - RegistryPropertyName = L"HardwareID"; break; - case DevicePropertyCompatibleIDs: - RegistryPropertyName = L"CompatibleIDs"; break; - case DevicePropertyDeviceDescription: - RegistryPropertyName = L"DeviceDesc"; break; - case DevicePropertyLocationInformation: - RegistryPropertyName = L"LocationInformation"; break; - case DevicePropertyUINumber: - RegistryPropertyName = L"UINumber"; break; - default: - /* Should not happen */ - ASSERT(FALSE); - return STATUS_UNSUCCESSFUL; - } - - DPRINT("Registry property %S\n", RegistryPropertyName); - - /* Open Enum key */ - Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL, - &EnumRoot, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status); - return Status; - } - - /* Open instance key */ - Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle, - &DeviceNode->InstancePath, KEY_READ); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Error opening InstancePath, Status=0x%08x\n", Status); - ZwClose(EnumRootHandle); - return Status; - } - - /* Allocate buffer to read as much data as required by the caller */ - ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, - Data[0]) + BufferLength; - ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength); - if (!ValueInformation) - { - ZwClose(KeyHandle); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Read the value */ - RtlInitUnicodeString(&ValueName, RegistryPropertyName); - Status = ZwQueryValueKey(KeyHandle, &ValueName, - KeyValuePartialInformation, ValueInformation, - ValueInformationLength, - &ValueInformationLength); - ZwClose(KeyHandle); - - /* Return data */ - *ResultLength = ValueInformation->DataLength; - - if (!NT_SUCCESS(Status)) - { - ExFreePool(ValueInformation); - if (Status == STATUS_BUFFER_OVERFLOW) - return STATUS_BUFFER_TOO_SMALL; - DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status, *ResultLength); - return Status; - } - - /* FIXME: Verify the value (NULL-terminated, correct format). */ - RtlCopyMemory(PropertyBuffer, ValueInformation->Data, - ValueInformation->DataLength); - ExFreePool(ValueInformation); - - return STATUS_SUCCESS; - } - - case DevicePropertyBootConfiguration: - Length = 0; - if (DeviceNode->BootResources->Count != 0) - { - Length = IopCalculateResourceListSize(DeviceNode->BootResources); - } - Data = DeviceNode->BootResources; - break; - - /* FIXME: use a translated boot configuration instead */ - case DevicePropertyBootConfigurationTranslated: - Length = 0; - if (DeviceNode->BootResources->Count != 0) - { - Length = IopCalculateResourceListSize(DeviceNode->BootResources); - } - Data = DeviceNode->BootResources; - break; - - case DevicePropertyEnumeratorName: - /* A buffer overflow can't happen here, since InstancePath - * always contains the enumerator name followed by \\ */ - Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\'); - ASSERT(Ptr); - Length = (Ptr - DeviceNode->InstancePath.Buffer) * sizeof(WCHAR); - Data = DeviceNode->InstancePath.Buffer; - break; - - case DevicePropertyPhysicalDeviceObjectName: - Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject, - NULL, - 0, - &RequiredLength); - if (Status == STATUS_SUCCESS) - { - Length = 0; - Data = L""; - } - else if (Status == STATUS_INFO_LENGTH_MISMATCH) - { - ObjectNameInfoLength = RequiredLength; - ObjectNameInfo = ExAllocatePool(PagedPool, ObjectNameInfoLength); - if (!ObjectNameInfo) - return STATUS_INSUFFICIENT_RESOURCES; - - Status = ObQueryNameString(DeviceNode->PhysicalDeviceObject, + case DevicePropertyPhysicalDeviceObjectName: + + /* Sanity check for Unicode-sized string */ + ASSERT((BufferLength & 1) == 0); + + /* Allocate name buffer */ + Length = BufferLength + sizeof(OBJECT_NAME_INFORMATION); + ObjectNameInfo = ExAllocatePool(PagedPool, Length); + if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES; + + /* Query the PDO name */ + Status = ObQueryNameString(DeviceObject, ObjectNameInfo, - ObjectNameInfoLength, - &RequiredLength); - if (NT_SUCCESS(Status)) + Length, + ResultLength); + if (Status == STATUS_INFO_LENGTH_MISMATCH) { - Length = ObjectNameInfo->Name.Length; - Data = ObjectNameInfo->Name.Buffer; + /* It's up to the caller to try again */ + Status = STATUS_BUFFER_TOO_SMALL; } - else - return Status; + + /* Return if successful */ + if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length, + ObjectNameInfo->Name.Buffer); + + /* Let the caller know how big the name is */ + *ResultLength -= sizeof(OBJECT_NAME_INFORMATION); + break; + + /* Handle the registry-based properties */ + case DevicePropertyUINumber: + PIP_REGISTRY_DATA(REGSTR_VAL_UI_NUMBER, REG_DWORD); + case DevicePropertyLocationInformation: + PIP_REGISTRY_DATA(REGSTR_VAL_LOCATION_INFORMATION, REG_SZ); + case DevicePropertyDeviceDescription: + PIP_REGISTRY_DATA(REGSTR_VAL_DEVDESC, REG_SZ); + case DevicePropertyHardwareID: + PIP_REGISTRY_DATA(REGSTR_VAL_HARDWAREID, REG_MULTI_SZ); + case DevicePropertyCompatibleIDs: + PIP_REGISTRY_DATA(REGSTR_VAL_COMPATIBLEIDS, REG_MULTI_SZ); + case DevicePropertyBootConfiguration: + PIP_REGISTRY_DATA(REGSTR_VAL_BOOTCONFIG, REG_RESOURCE_LIST); + case DevicePropertyClassName: + PIP_REGISTRY_DATA(REGSTR_VAL_CLASS, REG_SZ); + case DevicePropertyClassGuid: + PIP_REGISTRY_DATA(REGSTR_VAL_CLASSGUID, REG_SZ); + case DevicePropertyDriverKeyName: + PIP_REGISTRY_DATA(REGSTR_VAL_DRIVER, REG_SZ); + case DevicePropertyManufacturer: + PIP_REGISTRY_DATA(REGSTR_VAL_MFG, REG_SZ); + case DevicePropertyFriendlyName: + PIP_REGISTRY_DATA(REGSTR_VAL_FRIENDLYNAME, REG_SZ); + case DevicePropertyContainerID: + //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7 + PIP_UNIMPLEMENTED(); + case DevicePropertyRemovalPolicy: + PIP_UNIMPLEMENTED(); + case DevicePropertyInstallState: + PIP_UNIMPLEMENTED(); + case DevicePropertyResourceRequirements: + PIP_UNIMPLEMENTED(); + case DevicePropertyAllocatedResources: + PIP_UNIMPLEMENTED(); + default: + return STATUS_INVALID_PARAMETER_2; + } + + /* Having a registry value name implies registry data */ + if (ValueName) + { + /* We know up-front how much data to expect */ + *ResultLength = BufferLength; + + /* Go get the data, use the LogConf subkey if necessary */ + Status = PiGetDeviceRegistryProperty(DeviceObject, + ValueType, + ValueName, + (DeviceProperty == + DevicePropertyBootConfiguration) ? + L"LogConf": NULL, + PropertyBuffer, + ResultLength); + } + else if (NT_SUCCESS(Status)) + { + /* We know up-front how much data to expect, check the caller's buffer */ + *ResultLength = ReturnLength; + if (ReturnLength <= BufferLength) + { + /* Buffer is all good, copy the data */ + RtlCopyMemory(PropertyBuffer, Data, ReturnLength); + + /* Check for properties that require a null-terminated string */ + if ((DeviceProperty == DevicePropertyEnumeratorName) || + (DeviceProperty == DevicePropertyPhysicalDeviceObjectName)) + { + /* Terminate the string */ + ((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL; + } + + /* This is the success path */ + Status = STATUS_SUCCESS; } else - return Status; - break; - - default: - return STATUS_INVALID_PARAMETER_2; + { + /* Failure path */ + Status = STATUS_BUFFER_TOO_SMALL; + } } - - /* Prepare returned values */ - *ResultLength = Length; - if (BufferLength < Length) - { - if (ObjectNameInfo != NULL) - ExFreePool(ObjectNameInfo); - - return STATUS_BUFFER_TOO_SMALL; - } - RtlCopyMemory(PropertyBuffer, Data, Length); - - /* NULL terminate the string (if required) */ - if (DeviceProperty == DevicePropertyEnumeratorName || - DeviceProperty == DevicePropertyPhysicalDeviceObjectName) - ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL; - - if (ObjectNameInfo != NULL) - ExFreePool(ObjectNameInfo); - - return STATUS_SUCCESS; + + /* Free any allocation we may have made, and return the status code */ + if (ObjectNameInfo) ExFreePool(ObjectNameInfo); + return Status; } /* diff --git a/ntoskrnl/io/pnpmgr/pnpres.c b/ntoskrnl/io/pnpmgr/pnpres.c index 88148901112..699e7970eed 100644 --- a/ntoskrnl/io/pnpmgr/pnpres.c +++ b/ntoskrnl/io/pnpmgr/pnpres.c @@ -18,30 +18,6 @@ IopDetectResourceConflict( IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor); -ULONG -NTAPI -IopCalculateResourceListSize( - IN PCM_RESOURCE_LIST ResourceList) -{ - ULONG Size, i, j; - PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; - - Size = FIELD_OFFSET(CM_RESOURCE_LIST, List); - for (i = 0; i < ResourceList->Count; i++) - { - pPartialResourceList = &ResourceList->List[i].PartialResourceList; - Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + - pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - for (j = 0; j < pPartialResourceList->Count; j++) - { - if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific) - Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize; - } - } - - return Size; -} - static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) @@ -533,7 +509,7 @@ IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode) 0, REG_RESOURCE_LIST, DeviceNode->ResourceList, - IopCalculateResourceListSize(DeviceNode->ResourceList)); + PnpDetermineResourceListSize(DeviceNode->ResourceList)); ZwClose(ControlKey); if (!NT_SUCCESS(Status)) @@ -634,25 +610,37 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 if (DeviceNode->ResourceList) { - WCHAR NameBuff[256]; + PWCHAR DeviceName = NULL; UNICODE_STRING NameU; UNICODE_STRING Suffix; - ULONG OldLength; + ULONG OldLength = 0; ASSERT(DeviceNode->ResourceListTranslated); - NameU.Buffer = NameBuff; - NameU.Length = 0; - NameU.MaximumLength = 256 * sizeof(WCHAR); - Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, DevicePropertyPhysicalDeviceObjectName, - NameU.MaximumLength, - NameU.Buffer, + 0, + NULL, &OldLength); - ASSERT(Status == STATUS_SUCCESS); + if ((OldLength != 0) && (Status == STATUS_BUFFER_TOO_SMALL)) + { + DeviceName = ExAllocatePool(NonPagedPool, OldLength); + ASSERT(DeviceName); - NameU.Length = (USHORT)OldLength; + IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, + DevicePropertyPhysicalDeviceObjectName, + OldLength, + DeviceName, + &OldLength); + + RtlInitUnicodeString(&NameU, DeviceName); + } + else + { + /* Some failure */ + ASSERT(!NT_SUCCESS(Status)); + return Status; + } RtlInitUnicodeString(&Suffix, L".Raw"); RtlAppendUnicodeStringToString(&NameU, &Suffix); @@ -662,7 +650,7 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 0, REG_RESOURCE_LIST, DeviceNode->ResourceList, - IopCalculateResourceListSize(DeviceNode->ResourceList)); + PnpDetermineResourceListSize(DeviceNode->ResourceList)); if (!NT_SUCCESS(Status)) { ZwClose(PnpMgrLevel2); @@ -680,8 +668,10 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 0, REG_RESOURCE_LIST, DeviceNode->ResourceListTranslated, - IopCalculateResourceListSize(DeviceNode->ResourceListTranslated)); + PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated)); ZwClose(PnpMgrLevel2); + ASSERT(DeviceName); + ExFreePool(DeviceName); if (!NT_SUCCESS(Status)) return Status; } @@ -718,7 +708,7 @@ IopTranslateDeviceResources( /* That's easy to translate a resource list. Just copy the * untranslated one and change few fields in the copy */ - ListSize = IopCalculateResourceListSize(DeviceNode->ResourceList); + ListSize = PnpDetermineResourceListSize(DeviceNode->ResourceList); DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceListTranslated) @@ -838,7 +828,7 @@ IopAssignDeviceResources( if (DeviceNode->BootResources) { - ListSize = IopCalculateResourceListSize(DeviceNode->BootResources); + ListSize = PnpDetermineResourceListSize(DeviceNode->BootResources); DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceList) diff --git a/ntoskrnl/io/pnpmgr/pnproot.c b/ntoskrnl/io/pnpmgr/pnproot.c index 6f1834e5298..fb05da9e8d5 100644 --- a/ntoskrnl/io/pnpmgr/pnproot.c +++ b/ntoskrnl/io/pnpmgr/pnproot.c @@ -1085,7 +1085,6 @@ PnpRootPdoPnpControl( default: DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; break; } diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c index 9fb099c8b10..30eb071c2d1 100644 --- a/ntoskrnl/kdbg/kdb.c +++ b/ntoskrnl/kdbg/kdb.c @@ -1710,6 +1710,11 @@ KdbpGetCommandLineSettings( p2 += 8; KdbDebugState |= KD_DEBUG_KDNOECHO; } + else if (!_strnicmp(p2, "FIRSTCHANCE", 11)) + { + p2 += 11; + KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways); + } p1 = p2; } diff --git a/ntoskrnl/ke/i386/exp.c b/ntoskrnl/ke/i386/exp.c index 38dded77062..ebc327fb58c 100644 --- a/ntoskrnl/ke/i386/exp.c +++ b/ntoskrnl/ke/i386/exp.c @@ -1082,10 +1082,11 @@ DispatchToUser: } /* 3rd strike, kill the process */ - DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n", + DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n", PsGetCurrentProcess()->ImageFileName, ExceptionRecord->ExceptionCode, - ExceptionRecord->ExceptionAddress); + ExceptionRecord->ExceptionAddress, + PsGetCurrentProcess()->SectionBaseAddress); ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, diff --git a/ntoskrnl/ke/i386/traphdlr.c b/ntoskrnl/ke/i386/traphdlr.c index 8c535103123..7e960432bd2 100644 --- a/ntoskrnl/ke/i386/traphdlr.c +++ b/ntoskrnl/ke/i386/traphdlr.c @@ -547,7 +547,7 @@ KiTrap02(VOID) // // Handled, return from interrupt // - __asm__ __volatile__ ("iret\n"); + KiIret(); } // diff --git a/ntoskrnl/mm/ARM3/contmem.c b/ntoskrnl/mm/ARM3/contmem.c index 0d7628bf88f..94c8650f6ef 100644 --- a/ntoskrnl/mm/ARM3/contmem.c +++ b/ntoskrnl/mm/ARM3/contmem.c @@ -352,8 +352,8 @@ MiFindContiguousMemory(IN PFN_NUMBER LowestPfn, do { /* Write the PTE address */ - Pfn1->PteAddress = PointerPte++; - Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte)); + Pfn1->PteAddress = PointerPte; + Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte++)); } while (Pfn1++ < EndPfn); /* Return the address */ @@ -502,6 +502,9 @@ MiFreeContiguousMemory(IN PVOID BaseAddress) ASSERT(Pfn1->u4.VerifierAllocation == 0); ASSERT(Pfn1->u3.e1.PrototypePte == 0); + /* Set the special pending delete marker */ + MI_SET_PFN_DELETED(Pfn1); + /* Keep going for assertions */ PointerPte++; } while (Pfn1++->u3.e1.EndOfAllocation == 0); @@ -531,12 +534,11 @@ MiFreeContiguousMemory(IN PVOID BaseAddress) // Loop all the pages // LastPage = PageFrameIndex + PageCount; + Pfn1 = MiGetPfnEntry(PageFrameIndex); do { - // - // Free each one, and move on - // - MmReleasePageMemoryConsumer(MC_NPPOOL, PageFrameIndex++); + /* Decrement the share count and move on */ + MiDecrementShareCount(Pfn1++, PageFrameIndex++); } while (PageFrameIndex < LastPage); // diff --git a/ntoskrnl/mm/ARM3/expool.c b/ntoskrnl/mm/ARM3/expool.c index c10d8c87d56..83d62b785ac 100644 --- a/ntoskrnl/mm/ARM3/expool.c +++ b/ntoskrnl/mm/ARM3/expool.c @@ -19,6 +19,8 @@ #undef ExAllocatePoolWithQuota #undef ExAllocatePoolWithQuotaTag +BOOLEAN AllowPagedPool = TRUE; + /* GLOBALS ********************************************************************/ ULONG ExpNumberOfPagedPools; @@ -28,6 +30,262 @@ PPOOL_DESCRIPTOR PoolVector[2]; PVOID PoolTrackTable; PKGUARDED_MUTEX ExpPagedPoolMutex; +/* Pool block/header/list access macros */ +#define POOL_ENTRY(x) (PPOOL_HEADER)((ULONG_PTR)(x) - sizeof(POOL_HEADER)) +#define POOL_FREE_BLOCK(x) (PLIST_ENTRY)((ULONG_PTR)(x) + sizeof(POOL_HEADER)) +#define POOL_BLOCK(x, i) (PPOOL_HEADER)((ULONG_PTR)(x) + ((i) * POOL_BLOCK_SIZE)) +#define POOL_NEXT_BLOCK(x) POOL_BLOCK((x), (x)->BlockSize) +#define POOL_PREV_BLOCK(x) POOL_BLOCK((x), -((x)->PreviousSize)) + +/* + * Pool list access debug macros, similar to Arthur's pfnlist.c work. + * Microsoft actually implements similar checks in the Windows Server 2003 SP1 + * pool code, but only for checked builds. + * + * As of Vista, however, an MSDN Blog entry by a Security Team Manager indicates + * that these checks are done even on retail builds, due to the increasing + * number of kernel-mode attacks which depend on dangling list pointers and other + * kinds of list-based attacks. + * + * For now, I will leave these checks on all the time, but later they are likely + * to be DBG-only, at least until there are enough kernel-mode security attacks + * against ReactOS to warrant the performance hit. + * + * For now, these are not made inline, so we can get good stack traces. + */ +PLIST_ENTRY +NTAPI +ExpDecodePoolLink(IN PLIST_ENTRY Link) +{ + return (PLIST_ENTRY)((ULONG_PTR)Link & ~1); +} + +PLIST_ENTRY +NTAPI +ExpEncodePoolLink(IN PLIST_ENTRY Link) +{ + return (PLIST_ENTRY)((ULONG_PTR)Link | 1); +} + +VOID +NTAPI +ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) +{ + if ((ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Flink)->Blink) != ListHead) || + (ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Blink)->Flink) != ListHead)) + { + KeBugCheckEx(BAD_POOL_HEADER, + 3, + (ULONG_PTR)ListHead, + (ULONG_PTR)ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Flink)->Blink), + (ULONG_PTR)ExpDecodePoolLink(ExpDecodePoolLink(ListHead->Blink)->Flink)); + } +} + +VOID +NTAPI +ExpInitializePoolListHead(IN PLIST_ENTRY ListHead) +{ + ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead); +} + +BOOLEAN +NTAPI +ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead) +{ + return (ExpDecodePoolLink(ListHead->Flink) == ListHead); +} + +VOID +NTAPI +ExpRemovePoolEntryList(IN PLIST_ENTRY Entry) +{ + PLIST_ENTRY Blink, Flink; + Flink = ExpDecodePoolLink(Entry->Flink); + Blink = ExpDecodePoolLink(Entry->Blink); + Flink->Blink = ExpEncodePoolLink(Blink); + Blink->Flink = ExpEncodePoolLink(Flink); +} + +PLIST_ENTRY +NTAPI +ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Entry, Flink; + Entry = ExpDecodePoolLink(ListHead->Flink); + Flink = ExpDecodePoolLink(Entry->Flink); + ListHead->Flink = ExpEncodePoolLink(Flink); + Flink->Blink = ExpEncodePoolLink(ListHead); + return Entry; +} + +PLIST_ENTRY +NTAPI +ExpRemovePoolTailList(IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Entry, Blink; + Entry = ExpDecodePoolLink(ListHead->Blink); + Blink = ExpDecodePoolLink(Entry->Blink); + ListHead->Blink = ExpEncodePoolLink(Blink); + Blink->Flink = ExpEncodePoolLink(ListHead); + return Entry; +} + +VOID +NTAPI +ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + PLIST_ENTRY Blink; + ExpCheckPoolLinks(ListHead); + Blink = ExpDecodePoolLink(ListHead->Blink); + Entry->Flink = ExpEncodePoolLink(ListHead); + Entry->Blink = ExpEncodePoolLink(Blink); + Blink->Flink = ExpEncodePoolLink(Entry); + ListHead->Blink = ExpEncodePoolLink(Entry); + ExpCheckPoolLinks(ListHead); +} + +VOID +NTAPI +ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + PLIST_ENTRY Flink; + ExpCheckPoolLinks(ListHead); + Flink = ExpDecodePoolLink(ListHead->Flink); + Entry->Flink = ExpEncodePoolLink(Flink); + Entry->Blink = ExpEncodePoolLink(ListHead); + Flink->Blink = ExpEncodePoolLink(Entry); + ListHead->Flink = ExpEncodePoolLink(Entry); + ExpCheckPoolLinks(ListHead); +} + +VOID +NTAPI +ExpCheckPoolHeader(IN PPOOL_HEADER Entry) +{ + PPOOL_HEADER PreviousEntry, NextEntry; + + /* Is there a block before this one? */ + if (Entry->PreviousSize) + { + /* Get it */ + PreviousEntry = POOL_PREV_BLOCK(Entry); + + /* The two blocks must be on the same page! */ + if (PAGE_ALIGN(Entry) != PAGE_ALIGN(PreviousEntry)) + { + /* Something is awry */ + KeBugCheckEx(BAD_POOL_HEADER, + 6, + (ULONG_PTR)PreviousEntry, + __LINE__, + (ULONG_PTR)Entry); + } + + /* This block should also indicate that it's as large as we think it is */ + if (PreviousEntry->BlockSize != Entry->PreviousSize) + { + /* Otherwise, someone corrupted one of the sizes */ + KeBugCheckEx(BAD_POOL_HEADER, + 5, + (ULONG_PTR)PreviousEntry, + __LINE__, + (ULONG_PTR)Entry); + } + } + else if (PAGE_ALIGN(Entry) != Entry) + { + /* If there's no block before us, we are the first block, so we should be on a page boundary */ + KeBugCheckEx(BAD_POOL_HEADER, + 7, + 0, + __LINE__, + (ULONG_PTR)Entry); + } + + /* This block must have a size */ + if (!Entry->BlockSize) + { + /* Someone must've corrupted this field */ + KeBugCheckEx(BAD_POOL_HEADER, + 8, + 0, + __LINE__, + (ULONG_PTR)Entry); + } + + /* Okay, now get the next block */ + NextEntry = POOL_NEXT_BLOCK(Entry); + + /* If this is the last block, then we'll be page-aligned, otherwise, check this block */ + if (PAGE_ALIGN(NextEntry) != NextEntry) + { + /* The two blocks must be on the same page! */ + if (PAGE_ALIGN(Entry) != PAGE_ALIGN(NextEntry)) + { + /* Something is messed up */ + KeBugCheckEx(BAD_POOL_HEADER, + 9, + (ULONG_PTR)NextEntry, + __LINE__, + (ULONG_PTR)Entry); + } + + /* And this block should think we are as large as we truly are */ + if (NextEntry->PreviousSize != Entry->BlockSize) + { + /* Otherwise, someone corrupted the field */ + KeBugCheckEx(BAD_POOL_HEADER, + 5, + (ULONG_PTR)NextEntry, + __LINE__, + (ULONG_PTR)Entry); + } + } +} + +VOID +NTAPI +ExpCheckPoolBlocks(IN PVOID Block) +{ + BOOLEAN FoundBlock; + SIZE_T Size = 0; + PPOOL_HEADER Entry; + + /* Get the first entry for this page, make sure it really is the first */ + Entry = PAGE_ALIGN(Block); + ASSERT(Entry->PreviousSize == 0); + + /* Now scan each entry */ + while (TRUE) + { + /* When we actually found our block, remember this */ + if (Entry == Block) FoundBlock = TRUE; + + /* Now validate this block header */ + ExpCheckPoolHeader(Entry); + + /* And go to the next one, keeping track of our size */ + Size += Entry->BlockSize; + Entry = POOL_NEXT_BLOCK(Entry); + + /* If we hit the last block, stop */ + if (Size >= (PAGE_SIZE / POOL_BLOCK_SIZE)) break; + + /* If we hit the end of the page, stop */ + if (PAGE_ALIGN(Entry) == Entry) break; + } + + /* We must've found our block, and we must have hit the end of the page */ + if ((PAGE_ALIGN(Entry) != Entry) || !(FoundBlock)) + { + /* Otherwise, the blocks are messed up */ + KeBugCheckEx(BAD_POOL_HEADER, 10, (ULONG_PTR)Block, __LINE__, (ULONG_PTR)Entry); + } +} + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -68,7 +326,11 @@ ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor, // NextEntry = PoolDescriptor->ListHeads; LastEntry = NextEntry + POOL_LISTS_PER_PAGE; - while (NextEntry < LastEntry) InitializeListHead(NextEntry++); + while (NextEntry < LastEntry) + { + ExpInitializePoolListHead(NextEntry); + NextEntry++; + } } VOID @@ -196,8 +458,8 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // Check for paged pool // - if (PoolType == PagedPool) return ExAllocatePagedPoolWithTag(PagedPool, NumberOfBytes, Tag); - + if (!(AllowPagedPool) && (PoolType == PagedPool)) return ExAllocatePagedPoolWithTag(PagedPool, NumberOfBytes, Tag); + // // Some sanity checks // @@ -239,8 +501,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // request would've been treated as a POOL_MAX_ALLOC earlier and resulted in // the direct allocation of pages. // - i = (NumberOfBytes + sizeof(POOL_HEADER) + sizeof(LIST_ENTRY) - 1) / - sizeof(POOL_HEADER); + i = (NumberOfBytes + sizeof(POOL_HEADER) + (POOL_BLOCK_SIZE - 1)) / POOL_BLOCK_SIZE; // // Loop in the free lists looking for a block if this size. Start with the @@ -252,7 +513,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // Are there any free entries available on this list? // - if (!IsListEmpty(ListHead)) + if (!ExpIsPoolListEmpty(ListHead)) { // // Acquire the pool lock now @@ -262,7 +523,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // And make sure the list still has entries // - if (IsListEmpty(ListHead)) + if (ExpIsPoolListEmpty(ListHead)) { // // Someone raced us (and won) before we had a chance to acquire @@ -281,7 +542,10 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // there is a guarantee that any block on this list will either be // of the correct size, or perhaps larger. // - Entry = (PPOOL_HEADER)RemoveHeadList(ListHead) - 1; + ExpCheckPoolLinks(ListHead); + Entry = POOL_ENTRY(ExpRemovePoolHeadList(ListHead)); + ExpCheckPoolLinks(ListHead); + ExpCheckPoolBlocks(Entry); ASSERT(Entry->BlockSize >= i); ASSERT(Entry->PoolType == 0); @@ -302,7 +566,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // turn it into a fragment that contains the leftover data // that we don't need to satisfy the caller's request // - FragmentEntry = Entry + i; + FragmentEntry = POOL_BLOCK(Entry, i); FragmentEntry->BlockSize = Entry->BlockSize - i; // @@ -314,7 +578,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // Now get the block that follows the new fragment and check // if it's still on the same page as us (and not at the end) // - NextEntry = FragmentEntry + FragmentEntry->BlockSize; + NextEntry = POOL_NEXT_BLOCK(FragmentEntry); if (PAGE_ALIGN(NextEntry) != NextEntry) { // @@ -346,14 +610,14 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // This is the entry that will actually end up holding the // allocation! // - Entry += Entry->BlockSize; + Entry = POOL_NEXT_BLOCK(Entry); Entry->PreviousSize = FragmentEntry->BlockSize; // // And now let's go to the entry after that one and check if // it's still on the same page, and not at the end // - NextEntry = Entry + i; + NextEntry = POOL_BLOCK(Entry, i); if (PAGE_ALIGN(NextEntry) != NextEntry) { // @@ -381,13 +645,15 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // "full" entry, which contains enough bytes for a linked list // and thus can be used for allocations (up to 8 bytes...) // + ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]); if (BlockSize != 1) { // // Insert the free entry into the free list for this size // - InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], - (PLIST_ENTRY)FragmentEntry + 1); + ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1], + POOL_FREE_BLOCK(FragmentEntry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry)); } } @@ -396,13 +662,16 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // and release the lock since we're done // Entry->PoolType = PoolType + 1; + ExpCheckPoolBlocks(Entry); ExUnlockPool(PoolDesc, OldIrql); // // Return the pool allocation // Entry->PoolTag = Tag; - return ++Entry; + (POOL_FREE_BLOCK(Entry))->Flink = NULL; + (POOL_FREE_BLOCK(Entry))->Blink = NULL; + return POOL_FREE_BLOCK(Entry); } } while (++ListHead != &PoolDesc->ListHeads[POOL_LISTS_PER_PAGE]); @@ -410,6 +679,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // There were no free entries left, so we have to allocate a new fresh page // Entry = MiAllocatePoolPages(PoolType, PAGE_SIZE); + ASSERT(Entry != NULL); Entry->Ulong1 = 0; Entry->BlockSize = i; Entry->PoolType = PoolType + 1; @@ -420,8 +690,8 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // to create now. The free bytes are the whole page minus what was allocated // and then converted into units of block headers. // - BlockSize = (PAGE_SIZE / sizeof(POOL_HEADER)) - i; - FragmentEntry = Entry + i; + BlockSize = (PAGE_SIZE / POOL_BLOCK_SIZE) - i; + FragmentEntry = POOL_BLOCK(Entry, i); FragmentEntry->Ulong1 = 0; FragmentEntry->BlockSize = BlockSize; FragmentEntry->PreviousSize = i; @@ -441,20 +711,24 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType, // // And insert the free entry into the free list for this block size // - InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], - (PLIST_ENTRY)FragmentEntry + 1); - + ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]); + ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1], + POOL_FREE_BLOCK(FragmentEntry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry)); + // // Release the pool lock // + ExpCheckPoolBlocks(Entry); ExUnlockPool(PoolDesc, OldIrql); } // // And return the pool allocation // + ExpCheckPoolBlocks(Entry); Entry->PoolTag = Tag; - return ++Entry; + return POOL_FREE_BLOCK(Entry); } /* @@ -485,7 +759,7 @@ ExFreePoolWithTag(IN PVOID P, POOL_TYPE PoolType; PPOOL_DESCRIPTOR PoolDesc; BOOLEAN Combined = FALSE; - + // // Check for paged pool // @@ -526,7 +800,7 @@ ExFreePoolWithTag(IN PVOID P, // // Get the pointer to the next entry // - NextEntry = Entry + BlockSize; + NextEntry = POOL_BLOCK(Entry, BlockSize); // // Acquire the pool lock @@ -536,6 +810,7 @@ ExFreePoolWithTag(IN PVOID P, // // Check if the next allocation is at the end of the page // + ExpCheckPoolBlocks(Entry); if (PAGE_ALIGN(NextEntry) != NextEntry) { // @@ -559,7 +834,10 @@ ExFreePoolWithTag(IN PVOID P, // The block is at least big enough to have a linked list, so go // ahead and remove it // - RemoveEntryList((PLIST_ENTRY)NextEntry + 1); + ExpCheckPoolLinks(POOL_FREE_BLOCK(NextEntry)); + ExpRemovePoolEntryList(POOL_FREE_BLOCK(NextEntry)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Flink)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Blink)); } // @@ -577,7 +855,7 @@ ExFreePoolWithTag(IN PVOID P, // // Great, grab that entry and check if it's free // - NextEntry = Entry - Entry->PreviousSize; + NextEntry = POOL_PREV_BLOCK(Entry); if (NextEntry->PoolType == 0) { // @@ -596,7 +874,10 @@ ExFreePoolWithTag(IN PVOID P, // The block is at least big enough to have a linked list, so go // ahead and remove it // - RemoveEntryList((PLIST_ENTRY)NextEntry + 1); + ExpCheckPoolLinks(POOL_FREE_BLOCK(NextEntry)); + ExpRemovePoolEntryList(POOL_FREE_BLOCK(NextEntry)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Flink)); + ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Blink)); } // @@ -618,7 +899,7 @@ ExFreePoolWithTag(IN PVOID P, // page, they could've all been combined). // if ((PAGE_ALIGN(Entry) == Entry) && - (PAGE_ALIGN(Entry + Entry->BlockSize) == Entry + Entry->BlockSize)) + (PAGE_ALIGN(POOL_NEXT_BLOCK(Entry)) == POOL_NEXT_BLOCK(Entry))) { // // In this case, release the pool lock, and free the page @@ -644,7 +925,7 @@ ExFreePoolWithTag(IN PVOID P, // Get the first combined block (either our original to begin with, or // the one after the original, depending if we combined with the previous) // - NextEntry = Entry + BlockSize; + NextEntry = POOL_NEXT_BLOCK(Entry); // // As long as the next block isn't on a page boundary, have it point @@ -656,7 +937,8 @@ ExFreePoolWithTag(IN PVOID P, // // Insert this new free block, and release the pool lock // - InsertHeadList(&PoolDesc->ListHeads[BlockSize - 1], (PLIST_ENTRY)Entry + 1); + ExpInsertPoolHeadList(&PoolDesc->ListHeads[BlockSize - 1], POOL_FREE_BLOCK(Entry)); + ExpCheckPoolLinks(POOL_FREE_BLOCK(Entry)); ExUnlockPool(PoolDesc, OldIrql); } diff --git a/ntoskrnl/mm/ARM3/hypermap.c b/ntoskrnl/mm/ARM3/hypermap.c index 80f371620a0..fca9e03929b 100644 --- a/ntoskrnl/mm/ARM3/hypermap.c +++ b/ntoskrnl/mm/ARM3/hypermap.c @@ -82,9 +82,7 @@ MiMapPageInHyperSpace(IN PEPROCESS Process, // Write the current PTE // PointerPte += Offset; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); // // Return the address @@ -176,9 +174,7 @@ MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages, // Set the correct PTE to write to, and set its new value // PointerPte--; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); } while (--NumberOfPages); // diff --git a/ntoskrnl/mm/ARM3/i386/init.c b/ntoskrnl/mm/ARM3/i386/init.c index c0226ebc8ac..7b7f6c4e7db 100644 --- a/ntoskrnl/mm/ARM3/i386/init.c +++ b/ntoskrnl/mm/ARM3/i386/init.c @@ -306,7 +306,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // then add the color tables and convert to pages // MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN); - MxPfnAllocation <<= 1; + //MxPfnAllocation <<= 1; MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2); MxPfnAllocation >>= PAGE_SHIFT; @@ -380,19 +380,13 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // with the old memory manager, so we'll create a "Shadow PFN Database" // instead, and arbitrarly start it at 0xB0000000. // - // We actually create two PFN databases, one for ReactOS starting here, - // and the next one used for ARM3, which starts right after. The MmPfnAllocation - // variable actually holds the size of both (the colored tables come after - // the ARM3 PFN database). - // - MmPfnDatabase[0] = (PVOID)0xB0000000; - MmPfnDatabase[1] = &MmPfnDatabase[0][MmHighestPhysicalPage]; - ASSERT(((ULONG_PTR)MmPfnDatabase[0] & (PDE_MAPPED_VA - 1)) == 0); + MmPfnDatabase = (PVOID)0xB0000000; + ASSERT(((ULONG_PTR)MmPfnDatabase & (PDE_MAPPED_VA - 1)) == 0); // // Non paged pool comes after the PFN database // - MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase[0] + + MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT)); // @@ -416,17 +410,11 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1)); while (StartPde <= EndPde) { - // - // Sanity check - // - ASSERT(StartPde->u.Hard.Valid == 0); - // // Get a page // TempPde.u.Hard.PageFrameNumber = MxGetNextPage(1); - ASSERT(TempPde.u.Hard.Valid == 1); - *StartPde = TempPde; + MI_WRITE_VALID_PTE(StartPde, TempPde); // // Zero out the page table @@ -443,23 +431,17 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // // Now we need pages for the page tables which will map initial NP // - StartPde = MiAddressToPde(MmPfnDatabase[0]); + StartPde = MiAddressToPde(MmPfnDatabase); EndPde = MiAddressToPde((PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); while (StartPde <= EndPde) { - // - // Sanity check - // - ASSERT(StartPde->u.Hard.Valid == 0); - // // Get a page // TempPde.u.Hard.PageFrameNumber = MxGetNextPage(1); - ASSERT(TempPde.u.Hard.Valid == 1); - *StartPde = TempPde; - + MI_WRITE_VALID_PTE(StartPde, TempPde); + // // Zero out the page table // @@ -489,9 +471,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // Use one of our contigous pages // TempPte.u.Hard.PageFrameNumber = PageFrameIndex++; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } // @@ -510,12 +490,14 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Initialize the color tables */ MiInitializeColorTables(); + /* ReactOS Stuff */ + extern KEVENT ZeroPageThreadEvent; + KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); + /* Build the PFN Database */ MiInitializePfnDatabase(LoaderBlock); + MmInitializeBalancer(MmAvailablePages, 0); - /* Call back into shitMM to setup the ReactOS PFN database */ - MmInitializePageList(); - // // Reset the descriptor back so we can create the correct memory blocks // @@ -552,9 +534,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PageFrameIndex = MiRemoveAnyPage(0); TempPde.u.Hard.PageFrameNumber = PageFrameIndex; TempPde.u.Hard.Global = FALSE; // Hyperspace is local! - ASSERT(StartPde->u.Hard.Valid == 0); - ASSERT(TempPde.u.Hard.Valid == 1); - *StartPde = TempPde; + MI_WRITE_VALID_PTE(StartPde, TempPde); /* Flush the TLB */ KeFlushCurrentTb(); diff --git a/ntoskrnl/mm/ARM3/iosup.c b/ntoskrnl/mm/ARM3/iosup.c index 1a174509382..d02d7d41847 100644 --- a/ntoskrnl/mm/ARM3/iosup.c +++ b/ntoskrnl/mm/ARM3/iosup.c @@ -90,8 +90,8 @@ MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, // Also translate the cache attribute // Pfn = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT); - IsIoMapping = (Pfn > MmHighestPhysicalPage) ? TRUE : FALSE; - if (!IsIoMapping) Pfn1 = MiGetPfnEntry(Pfn); + Pfn1 = MiGetPfnEntry(Pfn); + IsIoMapping = (Pfn1 == NULL) ? TRUE : FALSE; CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType]; // @@ -171,16 +171,11 @@ MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, // do { - // - // Start out with nothing - // - ASSERT(PointerPte->u.Hard.Valid == 0); - // // Write the PFN // TempPte.u.Hard.PageFrameNumber = Pfn++; - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (--PageCount); // @@ -219,7 +214,7 @@ MmUnmapIoSpace(IN PVOID BaseAddress, // // Is this an I/O mapping? // - if (Pfn > MmHighestPhysicalPage) + if (!MiGetPfnEntry(Pfn)) { // // Destroy the PTE diff --git a/ntoskrnl/mm/ARM3/mdlsup.c b/ntoskrnl/mm/ARM3/mdlsup.c index 1b95448fc43..7488e52544c 100644 --- a/ntoskrnl/mm/ARM3/mdlsup.c +++ b/ntoskrnl/mm/ARM3/mdlsup.c @@ -129,7 +129,7 @@ MmBuildMdlForNonPagedPool(IN PMDL Mdl) // // Check if this is an I/O mapping // - if (Pfn > MmHighestPhysicalPage) Mdl->MdlFlags |= MDL_IO_SPACE; + if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE; } /* @@ -416,9 +416,8 @@ MmMapLockedPagesSpecifyCache(IN PMDL Mdl, // // Write the PTE // - ASSERT(PointerPte->u.Hard.Valid == 0); TempPte.u.Hard.PageFrameNumber = *MdlPages; - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (++MdlPages < LastPage); // diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index 7e0b9a68e99..88b25c46d39 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -88,6 +88,90 @@ #define MM_DECOMMIT 0x10 #define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE) +// +// Specific PTE Definitions that map to the Memory Manager's Protection Mask Bits +// The Memory Manager's definition define the attributes that must be preserved +// and these PTE definitions describe the attributes in the hardware sense. This +// helps deal with hardware differences between the actual boolean expression of +// the argument. +// +// For example, in the logical attributes, we want to express read-only as a flag +// but on x86, it is writability that must be set. On the other hand, on x86, just +// like in the kernel, it is disabling the caches that requires a special flag, +// while on certain architectures such as ARM, it is enabling the cache which +// requires a flag. +// +#if defined(_M_IX86) || defined(_M_AMD64) +// +// Access Flags +// +#define PTE_READONLY 0 +#define PTE_EXECUTE 0 // Not worrying about NX yet +#define PTE_EXECUTE_READ 0 // Not worrying about NX yet +#define PTE_READWRITE 0x2 +#define PTE_WRITECOPY 0x200 +#define PTE_EXECUTE_READWRITE 0x0 +#define PTE_EXECUTE_WRITECOPY 0x200 +// +// Cache flags +// +#define PTE_ENABLE_CACHE 0 +#define PTE_DISABLE_CACHE 0x10 +#define PTE_WRITECOMBINED_CACHE 0x10 +#elif defined(_M_ARM) +#else +#error Define these please! +#endif +static const +ULONG +MmProtectToPteMask[32] = +{ + // + // These are the base MM_ protection flags + // + 0, + PTE_READONLY | PTE_ENABLE_CACHE, + PTE_EXECUTE | PTE_ENABLE_CACHE, + PTE_EXECUTE_READ | PTE_ENABLE_CACHE, + PTE_READWRITE | PTE_ENABLE_CACHE, + PTE_WRITECOPY | PTE_ENABLE_CACHE, + PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE, + // + // These OR in the MM_NOCACHE flag + // + 0, + PTE_READONLY | PTE_DISABLE_CACHE, + PTE_EXECUTE | PTE_DISABLE_CACHE, + PTE_EXECUTE_READ | PTE_DISABLE_CACHE, + PTE_READWRITE | PTE_DISABLE_CACHE, + PTE_WRITECOPY | PTE_DISABLE_CACHE, + PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE, + // + // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM + // + 0, + PTE_READONLY | PTE_ENABLE_CACHE, + PTE_EXECUTE | PTE_ENABLE_CACHE, + PTE_EXECUTE_READ | PTE_ENABLE_CACHE, + PTE_READWRITE | PTE_ENABLE_CACHE, + PTE_WRITECOPY | PTE_ENABLE_CACHE, + PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE, + // + // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining? + // + 0, + PTE_READONLY | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE, + PTE_READWRITE | PTE_WRITECOMBINED_CACHE, + PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE, + PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE, +}; + // // Assertions for session images, addresses, and PTEs // @@ -118,6 +202,12 @@ // #define MI_MAKE_SOFTWARE_PTE(p, x) ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS)) +// +// Marks a PTE as deleted +// +#define MI_SET_PFN_DELETED(x) ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1)) +#define MI_IS_PFN_DELETED(x) ((ULONG_PTR)((x)->PteAddress) & 1) + // // Special values for LoadedImports // @@ -134,13 +224,18 @@ // Special IRQL value (found in assertions) // #define MM_NOIRQL (KIRQL)0xFFFFFFFF - + // // FIXFIX: These should go in ex.h after the pool merge // -#define POOL_LISTS_PER_PAGE (PAGE_SIZE / sizeof(LIST_ENTRY)) +#ifdef _M_AMD64 +#define POOL_BLOCK_SIZE 16 +#else +#define POOL_BLOCK_SIZE 8 +#endif +#define POOL_LISTS_PER_PAGE (PAGE_SIZE / POOL_BLOCK_SIZE) #define BASE_POOL_TYPE_MASK 1 -#define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + sizeof(LIST_ENTRY))) +#define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE)) typedef struct _POOL_DESCRIPTOR { @@ -165,16 +260,30 @@ typedef struct _POOL_HEADER { struct { +#ifdef _M_AMD64 + ULONG PreviousSize:8; + ULONG PoolIndex:8; + ULONG BlockSize:8; + ULONG PoolType:8; +#else USHORT PreviousSize:9; USHORT PoolIndex:7; USHORT BlockSize:9; USHORT PoolType:7; +#endif }; ULONG Ulong1; }; +#ifdef _M_AMD64 + ULONG PoolTag; +#endif union { +#ifdef _M_AMD64 + PEPROCESS ProcessBilled; +#else ULONG PoolTag; +#endif struct { USHORT AllocatorBackTraceIndex; @@ -183,11 +292,8 @@ typedef struct _POOL_HEADER }; } POOL_HEADER, *PPOOL_HEADER; -// -// Everything depends on this -// -C_ASSERT(sizeof(POOL_HEADER) == 8); -C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY)); +C_ASSERT(sizeof(POOL_HEADER) == POOL_BLOCK_SIZE); +C_ASSERT(POOL_BLOCK_SIZE == sizeof(LIST_ENTRY)); extern ULONG ExpNumberOfPagedPools; extern POOL_DESCRIPTOR NonPagedPoolDescriptor; @@ -354,6 +460,29 @@ extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT]; #define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x]) #define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1]) +// +// Creates a valid kernel PTE with the given protection +// +FORCEINLINE +VOID +MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte, + IN PMMPTE MappingPte, + IN ULONG ProtectionMask, + IN PFN_NUMBER PageFrameNumber) +{ + /* Only valid for kernel, non-session PTEs */ + ASSERT(MappingPte > MiHighestUserPte); + ASSERT(!MI_IS_SESSION_PTE(MappingPte)); + ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP)); + + /* Start fresh */ + *NewPte = ValidKernelPte; + + /* Set the protection and page */ + NewPte->u.Hard.PageFrameNumber = PageFrameNumber; + NewPte->u.Long |= MmProtectToPteMask[ProtectionMask]; +} + // // Returns if the page is physically resident (ie: a large page) // FIXFIX: CISC/x86 only? @@ -369,6 +498,33 @@ MI_IS_PHYSICAL_ADDRESS(IN PVOID Address) return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid)); } +// +// Writes a valid PTE +// +VOID +FORCEINLINE +MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, + IN MMPTE TempPte) +{ + /* Write the valid PTE */ + ASSERT(PointerPte->u.Hard.Valid == 0); + ASSERT(TempPte.u.Hard.Valid == 1); + *PointerPte = TempPte; +} + +// +// Writes an invalid PTE +// +VOID +FORCEINLINE +MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, + IN MMPTE InvalidPte) +{ + /* Write the invalid PTE */ + ASSERT(InvalidPte.u.Hard.Valid == 0); + *PointerPte = InvalidPte; +} + NTSTATUS NTAPI MmArmInitSystem( @@ -584,18 +740,56 @@ MiAllocatePfn( IN ULONG Protection ); +VOID +NTAPI +MiInitializePfn( + IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN BOOLEAN Modified +); + +VOID +NTAPI +MiInitializePfnForOtherProcess( + IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN PFN_NUMBER PteFrame +); + +VOID +NTAPI +MiDecrementShareCount( + IN PMMPFN Pfn1, + IN PFN_NUMBER PageFrameIndex +); + PFN_NUMBER NTAPI MiRemoveAnyPage( IN ULONG Color ); +PFN_NUMBER +NTAPI +MiRemoveZeroPage( + IN ULONG Color +); + VOID NTAPI MiInsertPageInFreeList( IN PFN_NUMBER PageFrameIndex ); +PFN_NUMBER +NTAPI +MiDeleteSystemPageableVm( + IN PMMPTE PointerPte, + IN PFN_NUMBER PageCount, + IN ULONG Flags, + OUT PPFN_NUMBER ValidPages +); + PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry( diff --git a/ntoskrnl/mm/mmdbg.c b/ntoskrnl/mm/ARM3/mmdbg.c similarity index 95% rename from ntoskrnl/mm/mmdbg.c rename to ntoskrnl/mm/ARM3/mmdbg.c index fd11099e1fd..41260f224c3 100644 --- a/ntoskrnl/mm/mmdbg.c +++ b/ntoskrnl/mm/ARM3/mmdbg.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/mm/mmdbg.c + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/mm/ARM3/mmdbg.c * PURPOSE: Memory Manager support routines for the Kernel Debugger * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) */ @@ -9,10 +9,17 @@ /* INCLUDES *******************************************************************/ #include -#include "ARM3/miarm.h" #define NDEBUG #include +#line 16 "ARMÂł::DEBUGSUP" +#define MODULE_INVOLVED_IN_ARM3 +#include "../ARM3/miarm.h" + +#ifndef _WINKD_ +#define KdpDprintf DPRINT +#endif + /* GLOBALS ********************************************************************/ PMMPTE MmDebugPte = MiAddressToPte(MI_DEBUG_MAPPING); @@ -35,7 +42,6 @@ NTAPI MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, IN ULONG Flags) { - extern MMPTE ValidKernelPte; PFN_NUMBER Pfn; MMPTE TempPte; PVOID MappingBaseAddress; @@ -76,7 +82,7 @@ MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, MappingBaseAddress = MiPteToAddress(MmDebugPte); // - // + // Get the template // TempPte = ValidKernelPte; @@ -85,10 +91,8 @@ MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, // Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT); - // - // Check if this could be an I/O mapping - // - if (Pfn > MmHighestPhysicalPage) + /* Check if this could be an I/O mapping */ + if (!MiGetPfnEntry(Pfn)) { // // FIXME: We don't support this yet diff --git a/ntoskrnl/mm/ARM3/mminit.c b/ntoskrnl/mm/ARM3/mminit.c index 63be4f66ebc..1e79a23c6cf 100644 --- a/ntoskrnl/mm/ARM3/mminit.c +++ b/ntoskrnl/mm/ARM3/mminit.c @@ -341,13 +341,13 @@ MiSyncARM3WithROS(IN PVOID AddressStart, // // Puerile piece of junk-grade carbonized horseshit puss sold to the lowest bidder // - ULONG Pde = MiGetPdeOffset(AddressStart); - while (Pde <= MiGetPdeOffset(AddressEnd)) + ULONG Pde = ADDR_TO_PDE_OFFSET(AddressStart); + while (Pde <= ADDR_TO_PDE_OFFSET(AddressEnd)) { // // This both odious and heinous // - extern ULONG MmGlobalKernelPageDirectory[]; + extern ULONG MmGlobalKernelPageDirectory[1024]; MmGlobalKernelPageDirectory[Pde] = ((PULONG)PDE_BASE)[Pde]; Pde++; } @@ -387,10 +387,10 @@ MiComputeColorInformation(VOID) if (!MmSecondaryColors) { /* Get L2 cache information */ - L2Associativity = KiGetSecondLevelDCacheSize(); + L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity; /* The number of colors is the number of cache bytes by set/way */ - MmSecondaryColors = KiGetSecondLevelDCacheSize(); + MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize; if (L2Associativity) MmSecondaryColors /= L2Associativity; } @@ -439,7 +439,7 @@ MiInitializeColorTables(VOID) MMPTE TempPte = ValidKernelPte; /* The color table starts after the ARM3 PFN database */ - MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[1][MmHighestPhysicalPage + 1]; + MmFreePagesByColor[0] = (PMMCOLOR_TABLES)&MmPfnDatabase[MmHighestPhysicalPage + 1]; /* Loop the PTEs. We have two color tables for each secondary color */ PointerPte = MiAddressToPte(&MmFreePagesByColor[0][0]); @@ -453,9 +453,8 @@ MiInitializeColorTables(VOID) { /* Get a page and map it */ TempPte.u.Hard.PageFrameNumber = MxGetNextPage(1); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + /* Zero out the page */ RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); } @@ -585,8 +584,8 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) } /* Get the PTEs for this range */ - PointerPte = MiAddressToPte(&MmPfnDatabase[0][BasePage]); - LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[0][BasePage + PageCount]) - 1); + PointerPte = MiAddressToPte(&MmPfnDatabase[BasePage]); + LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[BasePage + PageCount]) - 1); DPRINT("MD Type: %lx Base: %lx Count: %lx\n", MdBlock->MemoryType, BasePage, PageCount); /* Loop them */ @@ -614,9 +613,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Write out this PTE */ PagesLeft++; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); /* Zero this page */ RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); @@ -625,49 +622,7 @@ MiMapPfnDatabase(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Next! */ PointerPte++; } - - /* Get the PTEs for this range */ - PointerPte = MiAddressToPte(&MmPfnDatabase[1][BasePage]); - LastPte = MiAddressToPte(((ULONG_PTR)&MmPfnDatabase[1][BasePage + PageCount]) - 1); - DPRINT("MD Type: %lx Base: %lx Count: %lx\n", MdBlock->MemoryType, BasePage, PageCount); - - /* Loop them */ - while (PointerPte <= LastPte) - { - /* We'll only touch PTEs that aren't already valid */ - if (PointerPte->u.Hard.Valid == 0) - { - /* Use the next free page */ - TempPte.u.Hard.PageFrameNumber = FreePage; - ASSERT(FreePageCount != 0); - - /* Consume free pages */ - FreePage++; - FreePageCount--; - if (!FreePageCount) - { - /* Out of memory */ - KeBugCheckEx(INSTALL_MORE_MEMORY, - MmNumberOfPhysicalPages, - FreePageCount, - MxOldFreeDescriptor.PageCount, - 1); - } - - /* Write out this PTE */ - PagesLeft++; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - - /* Zero this page */ - RtlZeroMemory(MiPteToAddress(PointerPte), PAGE_SIZE); - } - - /* Next! */ - PointerPte++; - } - + /* Do the next address range */ NextEntry = MdBlock->ListEntry.Flink; } @@ -706,9 +661,9 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock) if (MiIsRegularMemory(LoaderBlock, PageFrameIndex)) { /* Yes we do, set it up */ - Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PageFrameIndex); Pfn1->u4.PteFrame = StartupPdIndex; - Pfn1->PteAddress = (PMMPTE)PointerPde; + Pfn1->PteAddress = PointerPde; Pfn1->u2.ShareCount++; Pfn1->u3.e2.ReferenceCount = 1; Pfn1->u3.e1.PageLocation = ActiveAndValid; @@ -745,7 +700,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock) MmSizeOfNonPagedPoolInBytes))) { /* Get the PFN entry and make sure it too is valid */ - Pfn2 = MI_PFN_TO_PFNENTRY(PtePageIndex); + Pfn2 = MiGetPfnEntry(PtePageIndex); if ((MmIsAddressValid(Pfn2)) && (MmIsAddressValid(Pfn2 + 1))) { @@ -785,13 +740,13 @@ MiBuildPfnDatabaseZeroPage(VOID) PMMPDE PointerPde; /* Grab the lowest page and check if it has no real references */ - Pfn1 = MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage); + Pfn1 = MiGetPfnEntry(MmLowestPhysicalPage); if (!(MmLowestPhysicalPage) && !(Pfn1->u3.e2.ReferenceCount)) { /* Make it a bogus page to catch errors */ PointerPde = MiAddressToPde(0xFFFFFFFF); Pfn1->u4.PteFrame = PFN_FROM_PTE(PointerPde); - Pfn1->PteAddress = (PMMPTE)PointerPde; + Pfn1->PteAddress = PointerPde; Pfn1->u2.ShareCount++; Pfn1->u3.e2.ReferenceCount = 0xFFF0; Pfn1->u3.e1.PageLocation = ActiveAndValid; @@ -810,6 +765,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PMMPFN Pfn1; PMMPTE PointerPte; PMMPDE PointerPde; + KIRQL OldIrql; /* Now loop through the descriptors */ NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; @@ -860,14 +816,18 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Get the last page of this descriptor. Note we loop backwards */ PageFrameIndex += PageCount - 1; - Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PageFrameIndex); + + /* Lock the PFN Database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); while (PageCount--) { /* If the page really has no references, mark it as free */ if (!Pfn1->u3.e2.ReferenceCount) { + /* Add it to the free list */ Pfn1->u3.e1.CacheAttribute = MiNonCached; - //MiInsertPageInFreeList(PageFrameIndex); + MiInsertPageInFreeList(PageFrameIndex); } /* Go to the next page */ @@ -875,6 +835,9 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PageFrameIndex--; } + /* Release PFN database */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + /* Done with this block */ break; @@ -890,7 +853,7 @@ MiBuildPfnDatabaseFromLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Map these pages with the KSEG0 mapping that adds 0x80000000 */ PointerPte = MiAddressToPte(KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT)); - Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex); + Pfn1 = MiGetPfnEntry(PageFrameIndex); while (PageCount--) { /* Check if the page is really unused */ @@ -940,15 +903,15 @@ MiBuildPfnDatabaseSelf(VOID) PMMPFN Pfn1; /* Loop the PFN database page */ - PointerPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmLowestPhysicalPage)); - LastPte = MiAddressToPte(MI_PFN_TO_PFNENTRY(MmHighestPhysicalPage)); + PointerPte = MiAddressToPte(MiGetPfnEntry(MmLowestPhysicalPage)); + LastPte = MiAddressToPte(MiGetPfnEntry(MmHighestPhysicalPage)); while (PointerPte <= LastPte) { /* Make sure the page is valid */ if (PointerPte->u.Hard.Valid == 1) { /* Get the PFN entry and just mark it referenced */ - Pfn1 = MI_PFN_TO_PFNENTRY(PointerPte->u.Hard.PageFrameNumber); + Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber); Pfn1->u2.ShareCount = 1; Pfn1->u3.e2.ReferenceCount = 1; } @@ -1202,7 +1165,7 @@ MiAddHalIoMappings(VOID) /* Check how many PDEs the heap has */ PointerPde = MiAddressToPde(BaseAddress); - PdeCount = PDE_COUNT - MiGetPdeOffset(BaseAddress); + PdeCount = PDE_COUNT - ADDR_TO_PDE_OFFSET(BaseAddress); for (i = 0; i < PdeCount; i++) { /* Does the HAL own this mapping? */ @@ -1258,7 +1221,7 @@ MmDumpArmPfnDatabase(VOID) // for (i = 0; i <= MmHighestPhysicalPage; i++) { - Pfn1 = MI_PFN_TO_PFNENTRY(i); + Pfn1 = MiGetPfnEntry(i); if (!Pfn1) continue; // @@ -1486,10 +1449,8 @@ VOID NTAPI MiBuildPagedPool(VOID) { - PMMPTE PointerPte; - PMMPDE PointerPde; + PMMPTE PointerPte, PointerPde; MMPTE TempPte = ValidKernelPte; - MMPDE TempPde = ValidKernelPde; PFN_NUMBER PageFrameIndex; KIRQL OldIrql; ULONG Size, BitMapSize; @@ -1518,9 +1479,7 @@ MiBuildPagedPool(VOID) TempPte = ValidKernelPte; ASSERT(PD_COUNT == 1); TempPte.u.Hard.PageFrameNumber = MmSystemPageDirectory[0]; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + MI_WRITE_VALID_PTE(PointerPte, TempPte); // // Let's get back to paged pool work: size it up. @@ -1588,14 +1547,15 @@ MiBuildPagedPool(VOID) // OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - // - // Allocate a page and map the first paged pool PDE - // - PageFrameIndex = MmAllocPage(MC_NPPOOL); - TempPde.u.Hard.PageFrameNumber = PageFrameIndex; - ASSERT(PointerPde->u.Hard.Valid == 0); - ASSERT(TempPde.u.Hard.Valid == 1); - *PointerPde = TempPde; + /* Allocate a page and map the first paged pool PDE */ + PageFrameIndex = MiRemoveZeroPage(0); + TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + MI_WRITE_VALID_PTE(PointerPde, TempPte); + + /* Initialize the PFN entry for it */ + MiInitializePfnForOtherProcess(PageFrameIndex, + PointerPde, + MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]); // // Release the PFN database lock @@ -1607,7 +1567,7 @@ MiBuildPagedPool(VOID) // will be allocated to handle paged pool growth. This is where they'll have // to start. // - MmPagedPoolInfo.NextPdeForPagedPoolExpansion = (PMMPTE)(PointerPde + 1); + MmPagedPoolInfo.NextPdeForPagedPoolExpansion = PointerPde + 1; // // We keep track of each page via a bit, so check how big the bitmap will @@ -1847,7 +1807,7 @@ MmArmInitSystem(IN ULONG Phase, // Sync us up with ReactOS Mm // MiSyncARM3WithROS(MmNonPagedSystemStart, (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - 1)); - MiSyncARM3WithROS(MmPfnDatabase[0], (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); + MiSyncARM3WithROS(MmPfnDatabase, (PVOID)((ULONG_PTR)MmNonPagedPoolStart + MmSizeOfNonPagedPoolInBytes - 1)); MiSyncARM3WithROS((PVOID)HYPER_SPACE, (PVOID)(HYPER_SPACE + PAGE_SIZE - 1)); // @@ -2028,6 +1988,12 @@ MmArmInitSystem(IN ULONG Phase, /* Size up paged pool and build the shadow system page directory */ MiBuildPagedPool(); + + /* Debugger physical memory support is now ready to be used */ + MiDbgReadyForPhysical = TRUE; + + /* Initialize the loaded module list */ + MiInitializeLoadedModuleList(LoaderBlock); } // diff --git a/ntoskrnl/mm/ARM3/ncache.c b/ntoskrnl/mm/ARM3/ncache.c index 659811dc57b..d49d72f3054 100644 --- a/ntoskrnl/mm/ARM3/ncache.c +++ b/ntoskrnl/mm/ARM3/ncache.c @@ -154,9 +154,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes) // Set the PFN in the page and write it // TempPte.u.Hard.PageFrameNumber = PageFrameIndex; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (--PageCount); // diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c index 7455a100af1..05fdb2dcade 100644 --- a/ntoskrnl/mm/ARM3/pagfault.c +++ b/ntoskrnl/mm/ARM3/pagfault.c @@ -65,7 +65,7 @@ MiCheckPdeForPagedPool(IN PVOID Address) if (PointerPde->u.Hard.Valid == 0) { /* This seems to be making the assumption that one PDE is one page long */ - ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); + C_ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); // // Copy it from our double-mapped system page directory @@ -105,12 +105,13 @@ MiResolveDemandZeroFault(IN PVOID Address, OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); ASSERT(PointerPte->u.Hard.Valid == 0); - // - // Get a page - // - PageFrameNumber = MmAllocPage(MC_PPOOL); + /* Get a page */ + PageFrameNumber = MiRemoveAnyPage(0); DPRINT("New pool page: %lx\n", PageFrameNumber); + /* Initialize it */ + MiInitializePfn(PageFrameNumber, PointerPte, TRUE); + // // Release PFN lock // @@ -124,16 +125,10 @@ MiResolveDemandZeroFault(IN PVOID Address, /* Shouldn't see faults for user PTEs yet */ ASSERT(PointerPte > MiHighestUserPte); - // - // Build the PTE - // - TempPte = ValidKernelPte; - TempPte.u.Hard.PageFrameNumber = PageFrameNumber; - ASSERT(TempPte.u.Hard.Valid == 1); - ASSERT(PointerPte->u.Hard.Valid == 0); - *PointerPte = TempPte; - ASSERT(PointerPte->u.Hard.Valid == 1); - + /* Build the PTE */ + MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, PointerPte->u.Soft.Protection, PageFrameNumber); + MI_WRITE_VALID_PTE(PointerPte, TempPte); + // // It's all good now // diff --git a/ntoskrnl/mm/ARM3/pfnlist.c b/ntoskrnl/mm/ARM3/pfnlist.c index ff17eb0b3c8..fb24d9fdbff 100644 --- a/ntoskrnl/mm/ARM3/pfnlist.c +++ b/ntoskrnl/mm/ARM3/pfnlist.c @@ -16,6 +16,20 @@ #define MODULE_INVOLVED_IN_ARM3 #include "../ARM3/miarm.h" +#if DBG +#define ASSERT_LIST_INVARIANT(x) \ +do { \ + ASSERT(((x)->Total == 0 && \ + (x)->Flink == LIST_HEAD && \ + (x)->Blink == LIST_HEAD) || \ + ((x)->Total != 0 && \ + (x)->Flink != LIST_HEAD && \ + (x)->Blink != LIST_HEAD)); \ +} while (0) +#else +#define ASSERT_LIST_INVARIANT(x) +#endif + /* GLOBALS ********************************************************************/ BOOLEAN MmDynamicPfn; @@ -42,12 +56,28 @@ PMMPFNLIST MmPageLocationList[] = }; /* FUNCTIONS ******************************************************************/ +VOID +NTAPI +MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex) +{ + KIRQL OldIrql; + PVOID VirtualAddress; + PEPROCESS Process = PsGetCurrentProcess(); + + /* Map in hyperspace, then wipe it using XMMI or MEMSET */ + VirtualAddress = MiMapPageInHyperSpace(Process, PageFrameIndex, &OldIrql); + KeZeroPages(VirtualAddress, PAGE_SIZE); + MiUnmapPageInHyperSpace(Process, VirtualAddress, OldIrql); +} + VOID NTAPI MiInsertInListTail(IN PMMPFNLIST ListHead, IN PMMPFN Entry) { PFN_NUMBER OldBlink, EntryIndex = MiGetPfnEntryIndex(Entry); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT_LIST_INVARIANT(ListHead); /* Get the back link */ OldBlink = ListHead->Blink; @@ -69,6 +99,7 @@ MiInsertInListTail(IN PMMPFNLIST ListHead, /* And now the head points back to us, since we are last */ ListHead->Blink = EntryIndex; ListHead->Total++; + ASSERT_LIST_INVARIANT(ListHead); } VOID @@ -97,6 +128,7 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* Use the zero list */ ListHead = &MmZeroedPageListHead; + ASSERT_LIST_INVARIANT(ListHead); ListHead->Total++; /* Get the back link */ @@ -118,6 +150,7 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* And now the head points back to us, since we are last */ ListHead->Blink = EntryIndex; + ASSERT_LIST_INVARIANT(ListHead); /* Update the page location */ Pfn1->u3.e1.PageLocation = ZeroedPageList; @@ -136,6 +169,7 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex) /* Otherwise check if we reached the high threshold and signal the event */ KeSetEvent(MiHighMemoryEvent, 0, FALSE); } + #if 0 /* Get the page color */ Color = EntryIndex & MmSecondaryColorMask; @@ -177,7 +211,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) /* Make sure the PFN lock is held */ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - + /* Make sure the PFN entry isn't in-use */ ASSERT(Entry->u3.e1.WriteInProgress == 0); ASSERT(Entry->u3.e1.ReadInProgress == 0); @@ -187,7 +221,8 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) ListName = ListHead->ListName; ASSERT(ListHead != NULL); ASSERT(ListName <= FreePageList); - + ASSERT_LIST_INVARIANT(ListHead); + /* Remove one count */ ASSERT(ListHead->Total != 0); ListHead->Total--; @@ -205,7 +240,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) else { /* Set the list head's backlink instead */ - ListHead->Blink = OldFlink; + ListHead->Blink = OldBlink; } /* Check if the back entry is the list head */ @@ -222,7 +257,8 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) /* We are not on a list anymore */ Entry->u1.Flink = Entry->u2.Blink = 0; - + ASSERT_LIST_INVARIANT(ListHead); + /* FIXME: Deal with color list */ /* See if we hit any thresholds */ @@ -272,6 +308,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, /* Could be either on free or zero list */ ListHead = MmPageLocationList[Pfn1->u3.e1.PageLocation]; + ASSERT_LIST_INVARIANT(ListHead); ListName = ListHead->ListName; ASSERT(ListName <= FreePageList); @@ -307,12 +344,14 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, } /* We are not on a list anymore */ + ASSERT_LIST_INVARIANT(ListHead); Pfn1->u1.Flink = Pfn1->u2.Blink = 0; /* Zero flags but restore color and cache */ Pfn1->u3.e2.ShortFlags = 0; Pfn1->u3.e1.PageColor = OldColor; Pfn1->u3.e1.CacheAttribute = OldCache; + #if 0 // When switching to ARM3 /* Get the first page on the color list */ ColorTable = &MmFreePagesByColor[ListName][Color]; @@ -379,12 +418,13 @@ MiRemoveAnyPage(IN ULONG Color) { #endif /* Check the free list */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); PageIndex = MmFreePageListHead.Flink; Color = PageIndex & MmSecondaryColorMask; if (PageIndex == LIST_HEAD) { /* Check the zero list */ - ASSERT(MmFreePageListHead.Total == 0); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); PageIndex = MmZeroedPageListHead.Flink; Color = PageIndex & MmSecondaryColorMask; ASSERT(PageIndex != LIST_HEAD); @@ -408,18 +448,95 @@ MiRemoveAnyPage(IN ULONG Color) (Pfn1->u3.e1.PageLocation == ZeroedPageList)); ASSERT(Pfn1->u3.e2.ReferenceCount == 0); ASSERT(Pfn1->u2.ShareCount == 0); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); /* Return the page */ return PageIndex; } +PFN_NUMBER +NTAPI +MiRemoveZeroPage(IN ULONG Color) +{ + PFN_NUMBER PageIndex; + PMMPFN Pfn1; + BOOLEAN Zero; + + /* Make sure PFN lock is held and we have pages */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(MmAvailablePages != 0); + ASSERT(Color < MmSecondaryColors); + + /* Check the colored zero list */ +#if 0 // Enable when using ARM3 database */ + PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink; + if (PageIndex == LIST_HEAD) + { +#endif + /* Check the zero list */ + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + PageIndex = MmZeroedPageListHead.Flink; + Color = PageIndex & MmSecondaryColorMask; + if (PageIndex == LIST_HEAD) + { + ASSERT(MmZeroedPageListHead.Total == 0); + Zero = TRUE; +#if 0 // Enable when using ARM3 database */ + /* Check the colored free list */ + PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink; + if (PageIndex == LIST_HEAD) + { +#endif + /* Check the free list */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + PageIndex = MmFreePageListHead.Flink; + Color = PageIndex & MmSecondaryColorMask; + ASSERT(PageIndex != LIST_HEAD); + if (PageIndex == LIST_HEAD) + { + /* FIXME: Should check the standby list */ + ASSERT(MmZeroedPageListHead.Total == 0); + } +#if 0 // Enable when using ARM3 database */ + } +#endif + } +#if 0 // Enable when using ARM3 database */ + } +#endif + /* Sanity checks */ + Pfn1 = MiGetPfnEntry(PageIndex); + ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) || + (Pfn1->u3.e1.PageLocation == ZeroedPageList)); + + /* Remove the page from its list */ + PageIndex = MiRemovePageByColor(PageIndex, Color); + ASSERT(Pfn1 == MiGetPfnEntry(PageIndex)); + + /* Zero it, if needed */ + if (Zero) MiZeroPhysicalPage(PageIndex); + + /* Sanity checks */ + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + ASSERT(Pfn1->u2.ShareCount == 0); + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + + /* Return the page */ + return PageIndex; +} + + PMMPFN NTAPI MiRemoveHeadList(IN PMMPFNLIST ListHead) { PFN_NUMBER Entry, Flink; PMMPFN Pfn1; - + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT_LIST_INVARIANT(ListHead); + /* Get the entry that's currently first on the list */ Entry = ListHead->Flink; Pfn1 = MiGetPfnEntry(Entry); @@ -443,7 +560,8 @@ MiRemoveHeadList(IN PMMPFNLIST ListHead) /* We are not on a list anymore */ Pfn1->u1.Flink = Pfn1->u2.Blink = 0; ListHead->Total--; - + ASSERT_LIST_INVARIANT(ListHead); + /* Return the head element */ return Pfn1; } @@ -461,6 +579,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) PMMCOLOR_TABLES ColorTable; #endif /* Make sure the page index is valid */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); ASSERT((PageFrameIndex != 0) && (PageFrameIndex <= MmHighestPhysicalPage) && (PageFrameIndex >= MmLowestPhysicalPage)); @@ -477,6 +596,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Get the free page list and increment its count */ ListHead = &MmFreePageListHead; + ASSERT_LIST_INVARIANT(ListHead); ListHead->Total++; /* Get the last page on the list */ @@ -494,7 +614,8 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Now make the list head point back to us (since we go at the end) */ ListHead->Blink = PageFrameIndex; - + ASSERT_LIST_INVARIANT(ListHead); + /* And initialize our own list pointers */ Pfn1->u1.Flink = LIST_HEAD; Pfn1->u2.Blink = LastPage; @@ -502,7 +623,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) /* Set the list name and default priority */ Pfn1->u3.e1.PageLocation = FreePageList; Pfn1->u4.Priority = 3; - + /* Clear some status fields */ Pfn1->u4.InPageError = 0; Pfn1->u4.AweAllocation = 0; @@ -561,4 +682,207 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) } } +VOID +NTAPI +MiInitializePfn(IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN BOOLEAN Modified) +{ + PMMPFN Pfn1; + NTSTATUS Status; + PMMPTE PointerPtePte; + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + /* Setup the PTE */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->PteAddress = PointerPte; + + /* Check if this PFN is part of a valid address space */ + if (PointerPte->u.Hard.Valid == 1) + { + /* FIXME: TODO */ + ASSERT(FALSE); + } + + /* Otherwise this is a fresh page -- set it up */ + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u2.ShareCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; + ASSERT(Pfn1->u3.e1.Rom == 0); + Pfn1->u3.e1.Modified = Modified; + + /* Get the page table for the PTE */ + PointerPtePte = MiAddressToPte(PointerPte); + if (PointerPtePte->u.Hard.Valid == 0) + { + /* Make sure the PDE gets paged in properly */ + Status = MiCheckPdeForPagedPool(PointerPte); + if (!NT_SUCCESS(Status)) + { + /* Crash */ + KeBugCheckEx(MEMORY_MANAGEMENT, + 0x61940, + (ULONG_PTR)PointerPte, + (ULONG_PTR)PointerPtePte->u.Long, + (ULONG_PTR)MiPteToAddress(PointerPte)); + } + } + + /* Get the PFN for the page table */ + PageFrameIndex = PFN_FROM_PTE(PointerPtePte); + ASSERT(PageFrameIndex != 0); + Pfn1->u4.PteFrame = PageFrameIndex; + + /* Increase its share count so we don't get rid of it */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->u2.ShareCount++; +} + +PFN_NUMBER +NTAPI +MiAllocatePfn(IN PMMPTE PointerPte, + IN ULONG Protection) +{ + KIRQL OldIrql; + PFN_NUMBER PageFrameIndex; + MMPTE TempPte; + + /* Sanity check that we aren't passed a valid PTE */ + ASSERT(PointerPte->u.Hard.Valid == 0); + + /* Make an empty software PTE */ + MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE); + + /* Lock the PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Check if we're running low on pages */ + if (MmAvailablePages < 128) + { + DPRINT1("Warning, running low on memory: %d pages left\n", MmAvailablePages); + //MiEnsureAvailablePageOrWait(NULL, OldIrql); + } + + /* Grab a page */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + PageFrameIndex = MiRemoveAnyPage(0); + + /* Write the software PTE */ + MI_WRITE_INVALID_PTE(PointerPte, TempPte); + PointerPte->u.Soft.Protection |= Protection; + + /* Initialize its PFN entry */ + MiInitializePfn(PageFrameIndex, PointerPte, TRUE); + + /* Release the PFN lock and return the page */ + ASSERT_LIST_INVARIANT(&MmFreePageListHead); + ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + return PageFrameIndex; +} + +VOID +NTAPI +MiDecrementShareCount(IN PMMPFN Pfn1, + IN PFN_NUMBER PageFrameIndex) +{ + ASSERT(PageFrameIndex > 0); + ASSERT(MiGetPfnEntry(PageFrameIndex) != NULL); + ASSERT(Pfn1 == MiGetPfnEntry(PageFrameIndex)); + + /* Page must be in-use */ + if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) && + (Pfn1->u3.e1.PageLocation != StandbyPageList)) + { + /* Otherwise we have PFN corruption */ + KeBugCheckEx(PFN_LIST_CORRUPT, + 0x99, + PageFrameIndex, + Pfn1->u3.e1.PageLocation, + 0); + } + + /* Check if the share count is now 0 */ + ASSERT(Pfn1->u2.ShareCount < 0xF000000); + if (!--Pfn1->u2.ShareCount) + { + /* ReactOS does not handle these */ + ASSERT(Pfn1->u3.e1.PrototypePte == 0); + + /* Put the page in transition */ + Pfn1->u3.e1.PageLocation = TransitionPage; + + /* PFN lock must be held */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + /* Page should at least have one reference */ + ASSERT(Pfn1->u3.e2.ReferenceCount != 0); + if (Pfn1->u3.e2.ReferenceCount == 1) + { + /* In ReactOS, this path should always be hit with a deleted PFN */ + ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE); + + /* Clear the last reference */ + Pfn1->u3.e2.ReferenceCount = 0; + + /* + * OriginalPte is used by AweReferenceCount in ReactOS, but either + * ways we shouldn't be seeing RMAP entries at this point + */ + ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0); + ASSERT(Pfn1->OriginalPte.u.Long == 0); + + /* Mark the page temporarily as valid, we're going to make it free soon */ + Pfn1->u3.e1.PageLocation = ActiveAndValid; + + /* Bring it back into the free list */ + MiInsertPageInFreeList(PageFrameIndex); + } + else + { + /* Otherwise, just drop the reference count */ + InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount); + } + } +} + +VOID +NTAPI +MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, + IN PMMPTE PointerPte, + IN PFN_NUMBER PteFrame) +{ + PMMPFN Pfn1; + + /* Setup the PTE */ + Pfn1 = MiGetPfnEntry(PageFrameIndex); + Pfn1->PteAddress = PointerPte; + +#if 0 // When using ARM3 PFN + /* Make this a software PTE */ + MI_MAKE_SOFTWARE_PTE(&Pfn1->OriginalPte, MM_READWRITE); +#endif + + /* Setup the page */ + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u2.ShareCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; + Pfn1->u3.e1.Modified = TRUE; + Pfn1->u4.InPageError = FALSE; + + /* Did we get a PFN for the page table */ + if (PteFrame) + { + /* Store it */ + Pfn1->u4.PteFrame = PteFrame; + + /* Increase its share count so we don't get rid of it */ + Pfn1 = MiGetPfnEntry(PteFrame); + Pfn1->u2.ShareCount++; + } +} + /* EOF */ diff --git a/ntoskrnl/mm/ARM3/pool.c b/ntoskrnl/mm/ARM3/pool.c index 17c99223e00..849db1c9a91 100644 --- a/ntoskrnl/mm/ARM3/pool.c +++ b/ntoskrnl/mm/ARM3/pool.c @@ -264,6 +264,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // Get the page bit count // i = ((SizeInPages - 1) / 1024) + 1; + DPRINT1("Paged pool expansion: %d %x\n", i, SizeInPages); // // Check if there is enougn paged pool expansion space left @@ -325,23 +326,25 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // ASSERT(PointerPte->u.Hard.Valid == 0); - // - // Request a paged pool page and write the PFN for it - // - PageFrameNumber = MmAllocPage(MC_PPOOL); + /* Request a page */ + PageFrameNumber = MiRemoveAnyPage(0); TempPte.u.Hard.PageFrameNumber = PageFrameNumber; // // Save it into our double-buffered system page directory // /* This seems to be making the assumption that one PDE is one page long */ - ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); + C_ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); MmSystemPagePtes[(ULONG_PTR)PointerPte & (PAGE_SIZE - 1) / sizeof(MMPTE)] = TempPte; + /* Initialize the PFN */ + MiInitializePfnForOtherProcess(PageFrameNumber, + PointerPte, + MmSystemPageDirectory[(PointerPte - (PMMPTE)PDE_BASE) / PDE_COUNT]); + /* Write the actual PTE now */ - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); // // Move on to the next expansion address @@ -417,11 +420,8 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // KeFlushEntireTb(TRUE, TRUE); - // - // Setup a demand-zero writable PTE - // - TempPte.u.Long = 0; - MI_MAKE_WRITE_PAGE(&TempPte); + /* Setup a demand-zero writable PTE */ + MI_MAKE_SOFTWARE_PTE(&TempPte, MM_READWRITE); // // Find the first and last PTE, then loop them all @@ -590,10 +590,8 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, TempPte = ValidKernelPte; do { - // - // Allocate a page - // - PageFrameNumber = MmAllocPage(MC_NPPOOL); + /* Allocate a page */ + PageFrameNumber = MiRemoveAnyPage(0); /* Get the PFN entry for it and fill it out */ Pfn1 = MiGetPfnEntry(PageFrameNumber); @@ -605,9 +603,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, /* Write the PTE for it */ TempPte.u.Hard.PageFrameNumber = PageFrameNumber; - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte++ = TempPte; + MI_WRITE_VALID_PTE(PointerPte++, TempPte); } while (--SizeInPages > 0); // @@ -667,6 +663,11 @@ MiFreePoolPages(IN PVOID StartingVa) // NumberOfPages = End - i + 1; + /* Delete the actual pages */ + PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i; + FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL); + ASSERT(FreePages == NumberOfPages); + // // Acquire the paged pool lock // diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c index 8f1e6b732c1..eb577050a7d 100644 --- a/ntoskrnl/mm/ARM3/procsup.c +++ b/ntoskrnl/mm/ARM3/procsup.c @@ -31,8 +31,10 @@ MmDeleteKernelStack(IN PVOID StackBase, IN BOOLEAN GuiStack) { PMMPTE PointerPte; - PFN_NUMBER StackPages; + PFN_NUMBER StackPages, PageFrameNumber;//, PageTableFrameNumber; + PMMPFN Pfn1;//, Pfn2; ULONG i; + KIRQL OldIrql; // // This should be the guard page, so decrement by one @@ -46,6 +48,9 @@ MmDeleteKernelStack(IN PVOID StackBase, StackPages = BYTES_TO_PAGES(GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE); + /* Acquire the PFN lock */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + // // Loop them // @@ -56,10 +61,22 @@ MmDeleteKernelStack(IN PVOID StackBase, // if (PointerPte->u.Hard.Valid == 1) { - // - // Nuke it - // - MmReleasePageMemoryConsumer(MC_NPPOOL, PFN_FROM_PTE(PointerPte)); + /* Get the PTE's page */ + PageFrameNumber = PFN_FROM_PTE(PointerPte); + Pfn1 = MiGetPfnEntry(PageFrameNumber); +#if 0 // ARM3 might not own the page table, so don't take this risk. Leak it instead! + /* Now get the page of the page table mapping it */ + PageTableFrameNumber = Pfn1->u4.PteFrame; + Pfn2 = MiGetPfnEntry(PageTableFrameNumber); + + /* Remove a shared reference, since the page is going away */ + MiDecrementShareCount(Pfn2, PageTableFrameNumber); +#endif + /* Set the special pending delete marker */ + Pfn1->PteAddress = (PMMPTE)((ULONG_PTR)Pfn1->PteAddress | 1); + + /* And now delete the actual stack page */ + MiDecrementShareCount(Pfn1, PageFrameNumber); } // @@ -73,6 +90,9 @@ MmDeleteKernelStack(IN PVOID StackBase, // ASSERT(PointerPte->u.Hard.Valid == 0); + /* Release the PFN lock */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + // // Release the PTEs // @@ -87,7 +107,7 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, PFN_NUMBER StackPtes, StackPages; PMMPTE PointerPte, StackPte; PVOID BaseAddress; - MMPTE TempPte; + MMPTE TempPte, InvalidPte; KIRQL OldIrql; PFN_NUMBER PageFrameIndex; ULONG i; @@ -131,13 +151,12 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, if (GuiStack) PointerPte += BYTES_TO_PAGES(KERNEL_LARGE_STACK_SIZE - KERNEL_LARGE_STACK_COMMIT); - // - // Setup the template stack PTE - // - TempPte = ValidKernelPte; - MI_MAKE_LOCAL_PAGE(&TempPte); - MI_MAKE_DIRTY_PAGE(&TempPte); - TempPte.u.Hard.PageFrameNumber = 0; + + /* Setup the temporary invalid PTE */ + MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS); + + /* Setup the template stack PTE */ + MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte + 1, MM_READWRITE, 0); // // Acquire the PFN DB lock @@ -154,18 +173,16 @@ MmCreateKernelStack(IN BOOLEAN GuiStack, // PointerPte++; - // - // Get a page - // - PageFrameIndex = MmAllocPage(MC_NPPOOL); - TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + /* Get a page and write the current invalid PTE */ + PageFrameIndex = MiRemoveAnyPage(0); + MI_WRITE_INVALID_PTE(PointerPte, InvalidPte); + + /* Initialize the PFN entry for this page */ + MiInitializePfn(PageFrameIndex, PointerPte, 1); - // - // Write it - // - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; + /* Write the valid PTE */ + TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + MI_WRITE_VALID_PTE(PointerPte, TempPte); } // Bug #4835 @@ -191,7 +208,7 @@ MmGrowKernelStackEx(IN PVOID StackPointer, PMMPTE LimitPte, NewLimitPte, LastPte; PFN_NUMBER StackPages; KIRQL OldIrql; - MMPTE TempPte; + MMPTE TempPte, InvalidPte; PFN_NUMBER PageFrameIndex; // @@ -232,13 +249,8 @@ MmGrowKernelStackEx(IN PVOID StackPointer, LimitPte--; StackPages = (LimitPte - NewLimitPte + 1); - // - // Setup the template stack PTE - // - TempPte = ValidKernelPte; - MI_MAKE_LOCAL_PAGE(&TempPte); - MI_MAKE_DIRTY_PAGE(&TempPte); - TempPte.u.Hard.PageFrameNumber = 0; + /* Setup the temporary invalid PTE */ + MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS); // // Acquire the PFN DB lock @@ -250,16 +262,18 @@ MmGrowKernelStackEx(IN PVOID StackPointer, // while (LimitPte >= NewLimitPte) { - // - // Get a page - // - PageFrameIndex = MmAllocPage(MC_NPPOOL); - TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + /* Get a page and write the current invalid PTE */ + PageFrameIndex = MiRemoveAnyPage(0); + MI_WRITE_INVALID_PTE(LimitPte, InvalidPte); + + /* Initialize the PFN entry for this page */ + MiInitializePfn(PageFrameIndex, LimitPte, 1); + + /* Setup the template stack PTE */ + MI_MAKE_HARDWARE_PTE(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex); /* Write the valid PTE */ - ASSERT(LimitPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *LimitPte-- = TempPte; + MI_WRITE_VALID_PTE(LimitPte--, TempPte); } // diff --git a/ntoskrnl/mm/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c similarity index 99% rename from ntoskrnl/mm/sysldr.c rename to ntoskrnl/mm/ARM3/sysldr.c index fcecf3c8da5..d8f7157eb21 100644 --- a/ntoskrnl/mm/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Kernel -* LICENSE: GPL - See COPYING in the top level directory -* FILE: ntoskrnl/mm/sysldr.c +* LICENSE: BSD - See COPYING.ARM in the top level directory +* FILE: ntoskrnl/mm/ARM3/sysldr.c * PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files. * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * ReactOS Portable Systems Group @@ -15,7 +15,7 @@ #line 16 "ARMÂł::LOADER" #define MODULE_INVOLVED_IN_ARM3 -#include "./ARM3/miarm.h" +#include "../ARM3/miarm.h" /* GCC's incompetence strikes again */ __inline @@ -172,13 +172,11 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, while (PointerPte < LastPte) { /* Allocate a page */ - TempPte.u.Hard.PageFrameNumber = MmAllocPage(MC_NPPOOL); - + TempPte.u.Hard.PageFrameNumber = MiAllocatePfn(PointerPte, MM_EXECUTE); + /* Write it */ - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + /* Move on */ PointerPte++; } @@ -1451,15 +1449,13 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Copy the old data */ OldPte = *StartPte; ASSERT(OldPte.u.Hard.Valid == 1); - + /* Set page number from the loader's memory */ TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber; - + /* Write it */ - ASSERT(PointerPte->u.Hard.Valid == 0); - ASSERT(TempPte.u.Hard.Valid == 1); - *PointerPte = TempPte; - + MI_WRITE_VALID_PTE(PointerPte, TempPte); + /* Move on */ PointerPte++; StartPte++; diff --git a/ntoskrnl/mm/ARM3/virtual.c b/ntoskrnl/mm/ARM3/virtual.c index 88ff54f5dcc..a4dcea797b0 100644 --- a/ntoskrnl/mm/ARM3/virtual.c +++ b/ntoskrnl/mm/ARM3/virtual.c @@ -29,6 +29,114 @@ MiProtectVirtualMemory(IN PEPROCESS Process, /* PRIVATE FUNCTIONS **********************************************************/ +PFN_NUMBER +NTAPI +MiDeleteSystemPageableVm(IN PMMPTE PointerPte, + IN PFN_NUMBER PageCount, + IN ULONG Flags, + OUT PPFN_NUMBER ValidPages) +{ + PFN_NUMBER ActualPages = 0; + PETHREAD CurrentThread; + PMMPFN Pfn1, Pfn2; + PFN_NUMBER PageFrameIndex, PageTableIndex; + KIRQL OldIrql, LockIrql; + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* + * Now we must raise to APC_LEVEL and mark the thread as owner + * We don't actually implement a working set pushlock, so this is only + * for internal consistency (and blocking APCs) + */ + KeRaiseIrql(APC_LEVEL, &LockIrql); + CurrentThread = PsGetCurrentThread(); + KeEnterGuardedRegion(); + ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) && + (CurrentThread->OwnsSystemWorkingSetShared == 0)); + CurrentThread->OwnsSystemWorkingSetExclusive = 1; + + /* Loop all pages */ + while (PageCount) + { + /* Make sure there's some data about the page */ + if (PointerPte->u.Long) + { + /* As always, only handle current ARM3 scenarios */ + ASSERT(PointerPte->u.Soft.Prototype == 0); + ASSERT(PointerPte->u.Soft.Transition == 0); + + /* Normally this is one possibility -- freeing a valid page */ + if (PointerPte->u.Hard.Valid) + { + /* Get the page PFN */ + PageFrameIndex = PFN_FROM_PTE(PointerPte); + Pfn1 = MiGetPfnEntry(PageFrameIndex); + + /* Should not have any working set data yet */ + ASSERT(Pfn1->u1.WsIndex == 0); + + /* Actual valid, legitimate, pages */ + if (ValidPages) *ValidPages++; + + /* Get the page table entry */ + PageTableIndex = Pfn1->u4.PteFrame; + Pfn2 = MiGetPfnEntry(PageTableIndex); + + /* Lock the PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Delete it the page */ + MI_SET_PFN_DELETED(Pfn1); + MiDecrementShareCount(Pfn1, PageFrameIndex); + + /* Decrement the page table too */ + #if 0 // ARM3: Dont't trust this yet + MiDecrementShareCount(Pfn2, PageTableIndex); + #endif + + /* Release the PFN database */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + + /* Destroy the PTE */ + PointerPte->u.Long = 0; + } + + /* Actual legitimate pages */ + ActualPages++; + } + else + { + /* + * The only other ARM3 possibility is a demand zero page, which would + * mean freeing some of the paged pool pages that haven't even been + * touched yet, as part of a larger allocation. + * + * Right now, we shouldn't expect any page file information in the PTE + */ + ASSERT(PointerPte->u.Soft.PageFileHigh == 0); + + /* Destroy the PTE */ + PointerPte->u.Long = 0; + } + + /* Keep going */ + PointerPte++; + PageCount--; + } + + /* Re-enable APCs */ + ASSERT(KeAreAllApcsDisabled() == TRUE); + CurrentThread->OwnsSystemWorkingSetExclusive = 0; + KeLeaveGuardedRegion(); + KeLowerIrql(LockIrql); + + /* Flush the entire TLB */ + KeFlushEntireTb(TRUE, TRUE); + + /* Done */ + return ActualPages; +} + LONG MiGetExceptionInfo(IN PEXCEPTION_POINTERS ExceptionInfo, OUT PBOOLEAN HaveBadAddress, diff --git a/ntoskrnl/mm/elf.inc.h b/ntoskrnl/mm/elf.inc.h deleted file mode 100644 index 2360bffd1d2..00000000000 --- a/ntoskrnl/mm/elf.inc.h +++ /dev/null @@ -1,705 +0,0 @@ -#define NDEBUG -#include - -#include - -#ifndef __ELF_WORD_SIZE -#error __ELF_WORD_SIZE must be defined -#endif - -#include - -/* TODO: Intsafe should be made into a library, as it's generally useful */ -static __inline BOOLEAN Intsafe_CanAddULongPtr -( - IN ULONG_PTR Addend1, - IN ULONG_PTR Addend2 -) -{ - return Addend1 <= (MAXULONG_PTR - Addend2); -} - -#define Intsafe_CanAddSizeT Intsafe_CanAddULongPtr - -static __inline BOOLEAN Intsafe_CanAddULong32 -( - IN ULONG Addend1, - IN ULONG Addend2 -) -{ - return Addend1 <= (MAXULONG - Addend2); -} - -static __inline BOOLEAN Intsafe_AddULong32 -( - OUT PULONG32 Result, - IN ULONG Addend1, - IN ULONG Addend2 -) -{ - if(!Intsafe_CanAddULong32(Addend1, Addend2)) - return FALSE; - - *Result = Addend1 + Addend2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanAddULong64 -( - IN ULONG64 Addend1, - IN ULONG64 Addend2 -) -{ - return Addend1 <= (((ULONG64)-1) - Addend2); -} - -static __inline BOOLEAN Intsafe_AddULong64 -( - OUT PULONG64 Result, - IN ULONG64 Addend1, - IN ULONG64 Addend2 -) -{ - if(!Intsafe_CanAddULong64(Addend1, Addend2)) - return FALSE; - - *Result = Addend1 + Addend2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanMulULong32 -( - IN ULONG Factor1, - IN ULONG Factor2 -) -{ - return Factor1 <= (MAXULONG / Factor2); -} - -static __inline BOOLEAN Intsafe_MulULong32 -( - OUT PULONG32 Result, - IN ULONG Factor1, - IN ULONG Factor2 -) -{ - if(!Intsafe_CanMulULong32(Factor1, Factor2)) - return FALSE; - - *Result = Factor1 * Factor2; - return TRUE; -} - -static __inline BOOLEAN Intsafe_CanOffsetPointer -( - IN CONST VOID * Pointer, - IN SIZE_T Offset -) -{ - /* FIXME: (PVOID)MAXULONG_PTR isn't necessarily a valid address */ - return Intsafe_CanAddULongPtr((ULONG_PTR)Pointer, Offset); -} - -#if __ELF_WORD_SIZE == 32 -#define ElfFmtpAddSize Intsafe_AddULong32 -#define ElfFmtpReadAddr ElfFmtpReadULong -#define ElfFmtpReadOff ElfFmtpReadULong -#define ElfFmtpSafeReadAddr ElfFmtpSafeReadULong -#define ElfFmtpSafeReadOff ElfFmtpSafeReadULong -#define ElfFmtpSafeReadSize ElfFmtpSafeReadULong -#elif __ELF_WORD_SIZE == 64 -#define ElfFmtpAddSize Intsafe_AddULong64 -#define ElfFmtpReadAddr ElfFmtpReadULong64 -#define ElfFmtpReadOff ElfFmtpReadULong64 -#define ElfFmtpSafeReadAddr ElfFmtpSafeReadULong64 -#define ElfFmtpSafeReadOff ElfFmtpSafeReadULong64 -#define ElfFmtpSafeReadSize ElfFmtpSafeReadULong64 -#endif - -/* TODO: these are standard DDK/PSDK macros */ -#define RtlRetrieveUlonglong(DST_, SRC_) \ - (RtlCopyMemory((DST_), (SRC_), sizeof(ULONG64))) - -#ifndef RTL_FIELD_SIZE -#define RTL_FIELD_SIZE(TYPE_, FIELD_) (sizeof(((TYPE_ *)0)->FIELD_)) -#endif - -#ifndef RTL_SIZEOF_THROUGH_FIELD -#define RTL_SIZEOF_THROUGH_FIELD(TYPE_, FIELD_) \ - (FIELD_OFFSET(TYPE_, FIELD_) + RTL_FIELD_SIZE(TYPE_, FIELD_)) -#endif - -#ifndef RTL_CONTAINS_FIELD -#define RTL_CONTAINS_FIELD(P_, SIZE_, FIELD_) \ - ((ULONG_PTR)(P_) + (ULONG_PTR)(SIZE_) > (ULONG_PTR)&((P_)->FIELD_) + sizeof((P_)->FIELD_)) -#endif - -#define ELFFMT_FIELDS_EQUAL(TYPE1_, TYPE2_, FIELD_) \ - ( \ - (FIELD_OFFSET(TYPE1_, FIELD_) == FIELD_OFFSET(TYPE2_, FIELD_)) && \ - (RTL_FIELD_SIZE(TYPE1_, FIELD_) == RTL_FIELD_SIZE(TYPE2_, FIELD_)) \ - ) - -#define ELFFMT_MAKE_ULONG64(BYTE1_, BYTE2_, BYTE3_, BYTE4_, BYTE5_, BYTE6_, BYTE7_, BYTE8_) \ - ( \ - (((ULONG64)ELFFMT_MAKE_ULONG(BYTE1_, BYTE2_, BYTE3_, BYTE4_)) << 0) | \ - (((ULONG64)ELFFMT_MAKE_ULONG(BYTE5_, BYTE6_, BYTE7_, BYTE8_)) << 32) \ - ) - -#define ELFFMT_MAKE_ULONG(BYTE1_, BYTE2_, BYTE3_, BYTE4_) \ - ( \ - (((ULONG)ELFFMT_MAKE_USHORT(BYTE1_, BYTE2_)) << 0) | \ - (((ULONG)ELFFMT_MAKE_USHORT(BYTE3_, BYTE4_)) << 16) \ - ) - -#define ELFFMT_MAKE_USHORT(BYTE1_, BYTE2_) \ - ( \ - (((USHORT)(BYTE1_)) << 0) | \ - (((USHORT)(BYTE2_)) << 8) \ - ) - -static __inline ULONG64 ElfFmtpReadULong64 -( - IN ULONG64 Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&Input; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG64(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG64(p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return (ULONG64)-1; -} - -static __inline ULONG ElfFmtpReadULong -( - IN ULONG Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&Input; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG(p[0], p[1], p[2], p[3]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG(p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return MAXULONG; -} - -static __inline USHORT ElfFmtpReadUShort -( - IN USHORT Input, - IN ULONG DataType -) -{ - PUCHAR p; - - if(DataType == ELF_TARG_DATA) - return Input; - - p = (PUCHAR)&Input; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_USHORT(p[0], p[1]); - case ELFDATA2MSB: return ELFFMT_MAKE_USHORT(p[1], p[0]); - } - - ASSERT(FALSE); - return (USHORT)-1; -} - -static __inline ULONG64 ElfFmtpSafeReadULong64 -( - IN CONST ULONG64 * Input, - IN ULONG DataType -) -{ - PUCHAR p; - ULONG64 nSafeInput; - - RtlRetrieveUlonglong(&nSafeInput, Input); - - p = (PUCHAR)&nSafeInput; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG64(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG64(p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return (ULONG64)-1; -} - -static __inline ULONG ElfFmtpSafeReadULong -( - IN CONST ULONG32 * Input, - IN ULONG DataType -) -{ - PUCHAR p; - ULONG nSafeInput; - union - { - CONST ULONG32 *ConstInput; - ULONG32 *Input; - }pInput = {Input}; - - RtlRetrieveUlong(&nSafeInput, pInput.Input); - - if(DataType == ELF_TARG_DATA) - return nSafeInput; - - p = (PUCHAR)&nSafeInput; - - switch(DataType) - { - case ELFDATA2LSB: return ELFFMT_MAKE_ULONG(p[0], p[1], p[2], p[3]); - case ELFDATA2MSB: return ELFFMT_MAKE_ULONG(p[3], p[2], p[1], p[0]); - } - - ASSERT(FALSE); - return MAXULONG; -} - -static __inline BOOLEAN ElfFmtpIsPowerOf2(IN Elf_Addr Number) -{ - if(Number == 0) - return FALSE; - - return (Number & (Number - 1)) == 0; -} - -static __inline Elf_Addr ElfFmtpModPow2 -( - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size)); - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off)); - ASSERT(ElfFmtpIsPowerOf2(Alignment)); - return Address & (Alignment - 1); -} - -static __inline Elf_Addr ElfFmtpAlignDown -( - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Size)); - ASSERT(sizeof(Elf_Addr) == sizeof(Elf_Off)); - ASSERT(ElfFmtpIsPowerOf2(Alignment)); - return Address & ~(Alignment - 1); -} - -static __inline BOOLEAN ElfFmtpAlignUp -( - OUT Elf_Addr * AlignedAddress, - IN Elf_Addr Address, - IN Elf_Addr Alignment -) -{ - Elf_Addr nExcess = ElfFmtpModPow2(Address, Alignment); - - if(nExcess == 0) - { - *AlignedAddress = Address; - return nExcess == 0; - } - else - return ElfFmtpAddSize(AlignedAddress, Address, Alignment - nExcess); -} - -/* - References: - [1] Tool Interface Standards (TIS) Committee, "Executable and Linking Format - (ELF) Specification", Version 1.2 -*/ -NTSTATUS NTAPI -#if __ELF_WORD_SIZE == 32 -Elf32FmtCreateSection -#elif __ELF_WORD_SIZE == 64 -Elf64FmtCreateSection -#endif -( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb -) -{ - NTSTATUS nStatus; - const Elf_Ehdr * pehHeader; - const Elf_Phdr * pphPHdrs; - BOOLEAN fPageAligned; - ULONG nData; - ULONG nPHdrCount; - ULONG cbPHdrSize; - Elf_Off cbPHdrOffset; - PVOID pBuffer; - PMM_SECTION_SEGMENT pssSegments; - Elf_Addr nImageBase = 0; - Elf_Addr nEntryPoint; - ULONG32 nPrevVirtualEndOfSegment = 0; - ULONG i; - ULONG j; - - (void)Intsafe_AddULong64; - (void)Intsafe_MulULong32; - (void)ElfFmtpReadULong64; - (void)ElfFmtpSafeReadULong64; - (void)ElfFmtpReadULong; - -#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; } - - pBuffer = NULL; - - nStatus = STATUS_INVALID_IMAGE_FORMAT; - - /* Ensure the file contains the full header */ - /* - EXEFMT_LOAD_HEADER_SIZE is 8KB: enough to contain an ELF header (at least in - all the classes defined as of December 2004). If FileHeaderSize is less than - sizeof(Elf_Ehdr), it means the file itself is small enough not to contain a - full ELF header - */ - ASSERT(sizeof(Elf_Ehdr) <= EXEFMT_LOAD_HEADER_SIZE); - - if(FileHeaderSize < sizeof(Elf_Ehdr)) - DIE(("The file is truncated, doesn't contain the full header\n")); - - pehHeader = FileHeader; - ASSERT(((ULONG_PTR)pehHeader % TYPE_ALIGNMENT(Elf_Ehdr)) == 0); - - nData = pehHeader->e_ident[EI_DATA]; - - /* Validate the header */ - if(ElfFmtpReadUShort(pehHeader->e_ehsize, nData) < sizeof(Elf_Ehdr)) - DIE(("Inconsistent value for e_ehsize\n")); - - /* Calculate size and offset of the program headers */ - cbPHdrSize = ElfFmtpReadUShort(pehHeader->e_phentsize, nData); - - if(cbPHdrSize != sizeof(Elf_Phdr)) - DIE(("Inconsistent value for e_phentsize\n")); - - /* MAXUSHORT * MAXUSHORT < MAXULONG */ - nPHdrCount = ElfFmtpReadUShort(pehHeader->e_phnum, nData); - ASSERT(Intsafe_CanMulULong32(cbPHdrSize, nPHdrCount)); - cbPHdrSize *= nPHdrCount; - - cbPHdrOffset = ElfFmtpReadOff(pehHeader->e_phoff, nData); - - /* The initial header doesn't contain the program headers */ - if(cbPHdrOffset > FileHeaderSize || cbPHdrSize > (FileHeaderSize - cbPHdrOffset)) - { - NTSTATUS nReadStatus; - LARGE_INTEGER lnOffset; - PVOID pData; - ULONG cbReadSize; - - /* Will worry about this when ELF128 comes */ - ASSERT(sizeof(cbPHdrOffset) <= sizeof(lnOffset.QuadPart)); - - lnOffset.QuadPart = (LONG64)cbPHdrOffset; - - /* - We can't support executable files larger than 8 Exabytes - it's a limitation - of the I/O system (only 63-bit offsets are supported). Quote: - - [...] the total amount of printed material in the world is estimated to be - around a fifth of an exabyte. [...] [Source: Wikipedia] - */ - if(lnOffset.u.HighPart < 0) - DIE(("The program header is too far into the file\n")); - - nReadStatus = ReadFileCb - ( - File, - &lnOffset, - cbPHdrSize, - &pData, - &pBuffer, - &cbReadSize - ); - - if(!NT_SUCCESS(nReadStatus)) - { - nStatus = nReadStatus; - DIE(("ReadFile failed, status %08X\n", nStatus)); - } - - ASSERT(pData); - ASSERT(pBuffer); - ASSERT(Intsafe_CanOffsetPointer(pData, cbReadSize)); - - if(cbReadSize < cbPHdrSize) - DIE(("The file didn't contain the program headers\n")); - - /* Force the buffer to be aligned */ - if((ULONG_PTR)pData % TYPE_ALIGNMENT(Elf_Phdr)) - { - ASSERT(((ULONG_PTR)pBuffer % TYPE_ALIGNMENT(Elf_Phdr)) == 0); - RtlMoveMemory(pBuffer, pData, cbPHdrSize); - pphPHdrs = pBuffer; - } - else - pphPHdrs = pData; - } - else - { - ASSERT(Intsafe_CanAddSizeT(cbPHdrOffset, 0)); - ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbPHdrOffset)); - pphPHdrs = (PVOID)((ULONG_PTR)FileHeader + (ULONG_PTR)cbPHdrOffset); - } - - /* Allocate the segments */ - pssSegments = AllocateSegmentsCb(nPHdrCount); - - if(pssSegments == NULL) - { - nStatus = STATUS_INSUFFICIENT_RESOURCES; - DIE(("Out of memory\n")); - } - - ImageSectionObject->Segments = pssSegments; - - fPageAligned = TRUE; - - /* Fill in the segments */ - for(i = 0, j = 0; i < nPHdrCount; ++ i) - { - switch(ElfFmtpSafeReadULong(&pphPHdrs[i].p_type, nData)) - { - case PT_LOAD: - { - static const ULONG ProgramHeaderFlagsToProtect[8] = - { - PAGE_NOACCESS, /* 0 */ - PAGE_EXECUTE_READ, /* PF_X */ - PAGE_READWRITE, /* PF_W */ - PAGE_EXECUTE_READWRITE, /* PF_X | PF_W */ - PAGE_READONLY, /* PF_R */ - PAGE_EXECUTE_READ, /* PF_X | PF_R */ - PAGE_READWRITE, /* PF_W | PF_R */ - PAGE_EXECUTE_READWRITE /* PF_X | PF_W | PF_R */ - }; - - Elf_Size nAlignment; - Elf_Off nFileOffset; - Elf_Addr nVirtualAddr; - Elf_Size nAdj; - Elf_Size nVirtualSize = 0; - Elf_Size nFileSize = 0; - - ASSERT(j <= nPHdrCount); - - /* Retrieve and validate the segment alignment */ - nAlignment = ElfFmtpSafeReadSize(&pphPHdrs[i].p_align, nData); - - if(nAlignment == 0) - nAlignment = 1; - else if(!ElfFmtpIsPowerOf2(nAlignment)) - DIE(("Alignment of loadable segment isn't a power of 2\n")); - - if(nAlignment < PAGE_SIZE) - fPageAligned = FALSE; - - /* Retrieve the addresses and calculate the adjustment */ - nFileOffset = ElfFmtpSafeReadOff(&pphPHdrs[i].p_offset, nData); - nVirtualAddr = ElfFmtpSafeReadAddr(&pphPHdrs[i].p_vaddr, nData); - - nAdj = ElfFmtpModPow2(nFileOffset, nAlignment); - - if(nAdj != ElfFmtpModPow2(nVirtualAddr, nAlignment)) - DIE(("File and memory address of loadable segment not congruent modulo alignment\n")); - - /* Retrieve, adjust and align the file size and memory size */ - if(!ElfFmtpAddSize(&nFileSize, ElfFmtpSafeReadSize(&pphPHdrs[i].p_filesz, nData), nAdj)) - DIE(("Can't adjust the file size of loadable segment\n")); - - if(!ElfFmtpAddSize(&nVirtualSize, ElfFmtpSafeReadSize(&pphPHdrs[i].p_memsz, nData), nAdj)) - DIE(("Can't adjust the memory size of lodable segment\n")); - - if(!ElfFmtpAlignUp(&nVirtualSize, nVirtualSize, nAlignment)) - DIE(("Can't align the memory size of lodable segment\n")); - - if(nFileSize > nVirtualSize) - nFileSize = nVirtualSize; - - if(nVirtualSize > MAXULONG) - DIE(("Virtual image larger than 4GB\n")); - - ASSERT(nFileSize <= MAXULONG); - - pssSegments[j].Length = (ULONG)(nVirtualSize & 0xFFFFFFFF); - pssSegments[j].RawLength = (ULONG)(nFileSize & 0xFFFFFFFF); - - /* File offset */ - nFileOffset = ElfFmtpAlignDown(nFileOffset, nAlignment); - -#if __ELF_WORD_SIZE >= 64 - ASSERT(sizeof(nFileOffset) == sizeof(LONG64)); - - if(((LONG64)nFileOffset) < 0) - DIE(("File offset of loadable segment is too large\n")); -#endif - - pssSegments[j].FileOffset = (LONG64)nFileOffset; - - /* Virtual address */ - nVirtualAddr = ElfFmtpAlignDown(nVirtualAddr, nAlignment); - - if(j == 0) - { - /* First segment: its address is the base address of the image */ - nImageBase = nVirtualAddr; - pssSegments[j].VirtualAddress = 0; - - /* Several places make this assumption */ - if(pssSegments[j].FileOffset != 0) - DIE(("First loadable segment doesn't contain the ELF header\n")); - } - else - { - Elf_Size nVirtualOffset; - - /* Other segment: store the offset from the base address */ - if(nVirtualAddr <= nImageBase) - DIE(("Loadable segments are not sorted\n")); - - nVirtualOffset = nVirtualAddr - nImageBase; - - if(nVirtualOffset > MAXULONG) - DIE(("Virtual image larger than 4GB\n")); - - pssSegments[j].VirtualAddress = (ULONG)(nVirtualOffset & 0xFFFFFFFF); - - if(pssSegments[j].VirtualAddress != nPrevVirtualEndOfSegment) - DIE(("Loadable segments are not sorted and contiguous\n")); - } - - /* Memory protection */ - pssSegments[j].Protection = ProgramHeaderFlagsToProtect - [ - ElfFmtpSafeReadULong(&pphPHdrs[i].p_flags, nData) & (PF_R | PF_W | PF_X) - ]; - - /* Characteristics */ - /* - TODO: need to add support for the shared, non-pageable, non-cacheable and - discardable attributes. This involves extensions to the ELF format, so it's - nothing to be taken lightly - */ - if(pssSegments[j].Protection & PAGE_IS_EXECUTABLE) - { - ImageSectionObject->Executable = TRUE; - pssSegments[j].Characteristics = IMAGE_SCN_CNT_CODE; - } - else if(pssSegments[j].RawLength == 0) - pssSegments[j].Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA; - else - pssSegments[j].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA; - - /* - FIXME: see the TODO above. This is the safest way to load ELF drivers, for - now, if a bit wasteful of memory - */ - pssSegments[j].Characteristics |= IMAGE_SCN_MEM_NOT_PAGED; - - /* Copy-on-write */ - pssSegments[j].WriteCopy = TRUE; - - if(!Intsafe_AddULong32(&nPrevVirtualEndOfSegment, pssSegments[j].VirtualAddress, pssSegments[j].Length)) - DIE(("Virtual image larger than 4GB\n")); - - ++ j; - break; - } - } - } - - if(j == 0) - DIE(("No loadable segments\n")); - - ImageSectionObject->NrSegments = j; - - *Flags = - EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED | - EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP; - - if(fPageAligned) - *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED; - - nEntryPoint = ElfFmtpReadAddr(pehHeader->e_entry, nData); - - if(nEntryPoint < nImageBase || nEntryPoint - nImageBase > nPrevVirtualEndOfSegment) - DIE(("Entry point not within the virtual image\n")); - - ASSERT(nEntryPoint >= nImageBase); - ASSERT((nEntryPoint - nImageBase) <= MAXULONG); - ImageSectionObject->EntryPoint = nEntryPoint - nImageBase; - - /* TODO: support Wine executables and read these values from nt_headers */ - ImageSectionObject->ImageCharacteristics |= - IMAGE_FILE_EXECUTABLE_IMAGE | - IMAGE_FILE_LINE_NUMS_STRIPPED | - IMAGE_FILE_LOCAL_SYMS_STRIPPED | - (nImageBase > MAXULONG ? IMAGE_FILE_LARGE_ADDRESS_AWARE : 0) | - IMAGE_FILE_DEBUG_STRIPPED; - - if(nData == ELFDATA2LSB) - ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_BYTES_REVERSED_LO; - else if(nData == ELFDATA2MSB) - ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_BYTES_REVERSED_HI; - - /* Base address outside the possible address space */ - if(nImageBase > MAXULONG_PTR) - ImageSectionObject->ImageBase = EXEFMT_LOAD_BASE_NONE; - /* Position-independent image, base address doesn't matter */ - else if(nImageBase == 0) - ImageSectionObject->ImageBase = EXEFMT_LOAD_BASE_ANY; - /* Use the specified base address */ - else - ImageSectionObject->ImageBase = (ULONG_PTR)nImageBase; - - /* safest bet */ - ImageSectionObject->Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; - ImageSectionObject->MinorSubsystemVersion = 0; - ImageSectionObject->MajorSubsystemVersion = 4; - - /* Success, at last */ - nStatus = STATUS_SUCCESS; - -l_Return: - if(pBuffer) - ExFreePool(pBuffer); - - return nStatus; -} - -/* EOF */ diff --git a/ntoskrnl/mm/elf32.c b/ntoskrnl/mm/elf32.c deleted file mode 100644 index 4e56e4408fc..00000000000 --- a/ntoskrnl/mm/elf32.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/elf32.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ -#include -#define __ELF_WORD_SIZE 32 -#include "elf.inc.h" - -extern NTSTATUS NTAPI Elf64FmtCreateSection -( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb -); - -NTSTATUS NTAPI ElfFmtCreateSection -( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb -) -{ - ULONG nDataType; - const Elf32_Ehdr * pehTempHeader; - - ASSERT(FileHeader); - ASSERT(FileHeaderSize > 0); - ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize)); - ASSERT(File); - ASSERT(ImageSectionObject); - ASSERT(Flags); - ASSERT(ReadFileCb); - ASSERT(AllocateSegmentsCb); - - pehTempHeader = FileHeader; - ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf32_Ehdr)) == 0); - ASSERT(((ULONG_PTR)pehTempHeader % TYPE_ALIGNMENT(Elf64_Ehdr)) == 0); - - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_ident)); - - /* File too small to be identified */ - if(!RTL_CONTAINS_FIELD(pehTempHeader, FileHeaderSize, e_ident[EI_MAG3])) - return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT; - - /* Not an ELF file */ - if - ( - pehTempHeader->e_ident[EI_MAG0] != ELFMAG0 || - pehTempHeader->e_ident[EI_MAG1] != ELFMAG1 || - pehTempHeader->e_ident[EI_MAG2] != ELFMAG2 || - pehTempHeader->e_ident[EI_MAG3] != ELFMAG3 - ) - return STATUS_ROS_EXEFMT_UNKNOWN_FORMAT; - - /* Validate the data type */ - nDataType = pehTempHeader->e_ident[EI_DATA]; - - switch(nDataType) - { - case ELFDATA2LSB: - case ELFDATA2MSB: - break; - - default: - return STATUS_INVALID_IMAGE_FORMAT; - } - - /* Validate the version */ - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_version)); - - if - ( - pehTempHeader->e_ident[EI_VERSION] != EV_CURRENT || - ElfFmtpReadULong(pehTempHeader->e_version, nDataType) != EV_CURRENT - ) - return STATUS_INVALID_IMAGE_FORMAT; - - /* Validate the file type */ - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_type)); - - switch(ElfFmtpReadUShort(pehTempHeader->e_type, nDataType)) - { - case ET_DYN: ImageSectionObject->ImageCharacteristics |= IMAGE_FILE_DLL; - case ET_EXEC: break; - default: return STATUS_INVALID_IMAGE_FORMAT; - } - - /* Convert the target machine */ - ASSERT(ELFFMT_FIELDS_EQUAL(Elf32_Ehdr, Elf64_Ehdr, e_machine)); - ASSERT(ImageSectionObject->Machine == IMAGE_FILE_MACHINE_UNKNOWN); - - switch(ElfFmtpReadUShort(pehTempHeader->e_machine, nDataType)) - { - case EM_386: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_I386; break; - case EM_MIPS_RS3_LE: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_R3000; break; - -#if 0 - /* TODO: need to read e_flags for full identification */ - case EM_SH: break; -#endif - - case EM_ARM: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_ARM; break; - case EM_PPC: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_POWERPC; break; - case EM_IA_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_IA64; break; - case EM_ALPHA: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AXP64; break; - case EM_X86_64: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_AMD64; break; - case EM_M32R: ImageSectionObject->Machine = IMAGE_FILE_MACHINE_M32R; break; - } - - /* Call the appropriate handler for the class-specific fields */ - switch(pehTempHeader->e_ident[EI_CLASS]) - { - case ELFCLASS32: - return Elf32FmtCreateSection - ( - FileHeader, - FileHeaderSize, - File, - ImageSectionObject, - Flags, - ReadFileCb, - AllocateSegmentsCb - ); - - case ELFCLASS64: - return Elf64FmtCreateSection - ( - FileHeader, - FileHeaderSize, - File, - ImageSectionObject, - Flags, - ReadFileCb, - AllocateSegmentsCb - ); - } - - /* Unknown class */ - return STATUS_INVALID_IMAGE_FORMAT; -} - -/* EOF */ diff --git a/ntoskrnl/mm/elf64.c b/ntoskrnl/mm/elf64.c deleted file mode 100644 index 783f5a00534..00000000000 --- a/ntoskrnl/mm/elf64.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/elf64.c - * PURPOSE: No purpose listed. - * - * PROGRAMMERS: No programmer listed. - */ -#include -#define __ELF_WORD_SIZE 64 -#include "elf.inc.h" diff --git a/ntoskrnl/mm/freelist.c b/ntoskrnl/mm/freelist.c index b6b9806e4b0..c3156ec79e5 100644 --- a/ntoskrnl/mm/freelist.c +++ b/ntoskrnl/mm/freelist.c @@ -33,8 +33,7 @@ #define PHYSICAL_PAGE MMPFN #define PPHYSICAL_PAGE PMMPFN -/* The first array contains ReactOS PFNs, the second contains ARM3 PFNs */ -PPHYSICAL_PAGE MmPfnDatabase[2]; +PPHYSICAL_PAGE MmPfnDatabase; PFN_NUMBER MmAvailablePages; PFN_NUMBER MmResidentAvailablePages; @@ -448,82 +447,6 @@ MmDumpPfnDatabase(VOID) KeLowerIrql(OldIrql); } -VOID -NTAPI -MmInitializePageList(VOID) -{ - ULONG i; - PHYSICAL_PAGE UsedPage; - PMEMORY_ALLOCATION_DESCRIPTOR Md; - PLIST_ENTRY NextEntry; - ULONG NrSystemPages = 0; - - /* This is what a used page looks like */ - RtlZeroMemory(&UsedPage, sizeof(UsedPage)); - UsedPage.u3.e1.PageLocation = ActiveAndValid; - UsedPage.u3.e2.ReferenceCount = 1; - - /* Loop the memory descriptors */ - for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink; - NextEntry != &KeLoaderBlock->MemoryDescriptorListHead; - NextEntry = NextEntry->Flink) - { - /* Get the descriptor */ - Md = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* Skip bad memory */ - if ((Md->MemoryType == LoaderFirmwarePermanent) || - (Md->MemoryType == LoaderBBTMemory) || - (Md->MemoryType == LoaderSpecialMemory) || - (Md->MemoryType == LoaderBad)) - { - // - // We do not build PFN entries for this - // - continue; - } - else if ((Md->MemoryType == LoaderFree) || - (Md->MemoryType == LoaderLoadedProgram) || - (Md->MemoryType == LoaderFirmwareTemporary) || - (Md->MemoryType == LoaderOsloaderStack)) - { - /* Loop every page part of the block */ - for (i = 0; i < Md->PageCount; i++) - { - /* Mark it as a free page */ - MmPfnDatabase[0][Md->BasePage + i].u3.e1.PageLocation = FreePageList; - MiInsertInListTail(&MmFreePageListHead, - &MmPfnDatabase[0][Md->BasePage + i]); - MmAvailablePages++; - } - } - else - { - /* Loop every page part of the block */ - for (i = 0; i < Md->PageCount; i++) - { - /* Everything else is used memory */ - MmPfnDatabase[0][Md->BasePage + i] = UsedPage; - NrSystemPages++; - } - } - } - - /* Finally handle the pages describing the PFN database themselves */ - for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++) - { - /* Mark it as used kernel memory */ - MmPfnDatabase[0][i] = UsedPage; - NrSystemPages++; - } - - KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); - DPRINT("Pages: %x %x\n", MmAvailablePages, NrSystemPages); - MmInitializeBalancer(MmAvailablePages, NrSystemPages); -} - VOID NTAPI MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead) @@ -688,7 +611,7 @@ MmAllocPage(ULONG Type) MmAvailablePages--; - PfnOffset = PageDescriptor - MmPfnDatabase[0]; + PfnOffset = MiGetPfnEntryIndex(PageDescriptor); if ((NeedClear) && (Type != MC_SYSTEM)) { MiZeroPage(PfnOffset); @@ -754,7 +677,7 @@ MmZeroPageThreadMain(PVOID Ignored) PageDescriptor = MiRemoveHeadList(&MmFreePageListHead); /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); - Pfn = PageDescriptor - MmPfnDatabase[0]; + Pfn = MiGetPfnEntryIndex(PageDescriptor); Status = MiZeroPage(Pfn); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); diff --git a/ntoskrnl/mm/mmfault.c b/ntoskrnl/mm/mmfault.c index f908e608bed..c4a81739c38 100644 --- a/ntoskrnl/mm/mmfault.c +++ b/ntoskrnl/mm/mmfault.c @@ -284,13 +284,13 @@ MmAccessFault(IN BOOLEAN StoreInstruction, * can go away. */ MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address); - if ((!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)) || + if ((!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) || ((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3))) { // // Hand it off to more competent hands... // - DPRINT1("ARM3 fault\n"); + DPRINT("ARM3 fault %p\n", MemoryArea); return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation); } diff --git a/ntoskrnl/mm/mminit.c b/ntoskrnl/mm/mminit.c index cb10634fdc2..83c45f145b9 100644 --- a/ntoskrnl/mm/mminit.c +++ b/ntoskrnl/mm/mminit.c @@ -109,7 +109,7 @@ MiInitSystemMemoryAreas() // // Protect the PFN database // - BaseAddress = MmPfnDatabase[0]; + BaseAddress = MmPfnDatabase; Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC, &BaseAddress, @@ -292,8 +292,8 @@ MiDbgDumpAddressSpace(VOID) (ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize, "Paged Pool"); DPRINT1(" 0x%p - 0x%p\t%s\n", - MmPfnDatabase[0], - (ULONG_PTR)MmPfnDatabase[0] + (MxPfnAllocation << PAGE_SHIFT), + MmPfnDatabase, + (ULONG_PTR)MmPfnDatabase + (MxPfnAllocation << PAGE_SHIFT), "PFN Database"); DPRINT1(" 0x%p - 0x%p\t%s\n", MmNonPagedPoolStart, @@ -371,18 +371,8 @@ MmInitSystem(IN ULONG Phase, /* Dump memory descriptors */ if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); - // - // Initialize ARMÂł in phase 0 - // + /* Initialize ARMÂł in phase 0 */ MmArmInitSystem(0, KeLoaderBlock); - -#if defined(_WINKD_) - // - // Everything required for the debugger to read and write - // physical memory is now set up - // - MiDbgReadyForPhysical = TRUE; -#endif /* Put the paged pool after the loaded modules */ MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart + @@ -394,15 +384,10 @@ MmInitSystem(IN ULONG Phase, /* Dump the address space */ MiDbgDumpAddressSpace(); - - /* Initialize paged pool */ - MmInitializePagedPool(); - - /* Initialize the loaded module list */ - MiInitializeLoadedModuleList(LoaderBlock); } else if (Phase == 1) { + MmInitializePagedPool(); MiInitializeUserPfnBitmap(); MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); MmInitializeRmapList(); @@ -453,7 +438,9 @@ MmInitSystem(IN ULONG Phase, } else if (Phase == 2) { - + /* Enough fun for now */ + extern BOOLEAN AllowPagedPool; + AllowPagedPool = FALSE; } return TRUE; diff --git a/ntoskrnl/ntoskrnl-generic.rbuild b/ntoskrnl/ntoskrnl-generic.rbuild index 5dc63c62e56..c89b9c97683 100644 --- a/ntoskrnl/ntoskrnl-generic.rbuild +++ b/ntoskrnl/ntoskrnl-generic.rbuild @@ -397,6 +397,7 @@ iosup.c largepag.c mdlsup.c + mmdbg.c mminit.c mmsup.c ncache.c @@ -404,6 +405,7 @@ pfnlist.c pool.c procsup.c + sysldr.c syspte.c virtual.c @@ -411,9 +413,6 @@ balance.c freelist.c marea.c - - mmdbg.c - mmfault.c mminit.c mpw.c @@ -425,7 +424,6 @@ region.c rmap.c section.c - sysldr.c virtual.c elf32.c diff --git a/ntoskrnl/ps/query.c b/ntoskrnl/ps/query.c index b4c2abaefea..342c818945e 100644 --- a/ntoskrnl/ps/query.c +++ b/ntoskrnl/ps/query.c @@ -5,6 +5,7 @@ * PURPOSE: Process Manager: Thread/Process Query/Set Information * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Thomas Weidenmueller (w3seek@reactos.org) + * Eric Kohl */ /* INCLUDES ******************************************************************/ @@ -735,6 +736,42 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle, ObDereferenceObject(Process); break; + case ProcessBreakOnTermination: + + /* Set the return length*/ + Length = sizeof(ULONG); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) break; + + /* Enter SEH for writing back data */ + _SEH2_TRY + { + /* Return the BreakOnTermination state */ + *(PULONG)ProcessInformation = Process->BreakOnTermination; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* Dereference the process */ + ObDereferenceObject(Process); + break; + /* Per-process security cookie */ case ProcessCookie: @@ -831,6 +868,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, PROCESS_SESSION_INFORMATION SessionInfo = {0}; PROCESS_PRIORITY_CLASS PriorityClass = {0}; PVOID ExceptionPort; + ULONG Break; PAGED_CODE(); /* Verify Information Class validity */ @@ -887,8 +925,9 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -931,8 +970,9 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -983,8 +1023,9 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1051,7 +1092,8 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1146,6 +1188,48 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, Status = STATUS_NOT_IMPLEMENTED; break; + case ProcessBreakOnTermination: + + /* Check buffer length */ + if (ProcessInformationLength != sizeof(ULONG)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Enter SEH for direct buffer read */ + _SEH2_TRY + { + Break = *(PULONG)ProcessInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Break = 0; + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); + } + _SEH2_END; + + /* Setting 'break on termination' requires the SeDebugPrivilege */ + if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode)) + { + Status = STATUS_PRIVILEGE_NOT_HELD; + break; + } + + /* Set or clear the flag */ + if (Break) + { + PspSetProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT); + } + else + { + PspClearProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT); + } + + break; + /* We currently don't implement any of these */ case ProcessLdtInformation: case ProcessLdtSize: @@ -1221,7 +1305,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle, Access = THREAD_SET_THREAD_TOKEN; } - /* Reference the process */ + /* Reference the thread */ Status = ObReferenceObjectByHandle(ThreadHandle, Access, PsThreadType, @@ -1251,8 +1335,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1286,8 +1371,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1331,8 +1417,8 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } _SEH2_END; @@ -1398,8 +1484,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1424,8 +1511,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1450,8 +1538,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1497,8 +1586,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; @@ -1523,8 +1613,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); } _SEH2_END; diff --git a/ntoskrnl/se/access.c b/ntoskrnl/se/access.c index 953166f98b3..fdf4f1376b3 100644 --- a/ntoskrnl/se/access.c +++ b/ntoskrnl/se/access.c @@ -30,11 +30,12 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread, OUT PSECURITY_SUBJECT_CONTEXT SubjectContext) { BOOLEAN CopyOnOpen, EffectiveOnly; + PAGED_CODE(); - + /* Save the unique ID */ SubjectContext->ProcessAuditId = Process->UniqueProcessId; - + /* Check if we have a thread */ if (!Thread) { @@ -49,7 +50,7 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread, &EffectiveOnly, &SubjectContext->ImpersonationLevel); } - + /* Get the primary token */ SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process); } @@ -75,7 +76,7 @@ NTAPI SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { PAGED_CODE(); - + KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE); } @@ -88,7 +89,7 @@ NTAPI SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { PAGED_CODE(); - + ExReleaseResourceLite(&SepSubjectContextLock); KeLeaveCriticalRegion(); } @@ -101,12 +102,12 @@ NTAPI SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { PAGED_CODE(); - + if (SubjectContext->PrimaryToken != NULL) { ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken); } - + if (SubjectContext->ClientToken != NULL) { ObDereferenceObject(SubjectContext->ClientToken); @@ -127,6 +128,7 @@ SeCreateAccessStateEx(IN PETHREAD Thread, { ACCESS_MASK AccessMask = Access; PTOKEN Token; + PAGED_CODE(); /* Map the Generic Acess to Specific Access if we have a Mapping */ @@ -150,9 +152,9 @@ SeCreateAccessStateEx(IN PETHREAD Thread, ExpAllocateLocallyUniqueId(&AccessState->OperationID); /* Get the Token to use */ - Token = AccessState->SubjectSecurityContext.ClientToken ? - (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken : - (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken; + Token = AccessState->SubjectSecurityContext.ClientToken ? + (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken : + (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken; /* Check for Travers Privilege */ if (Token->TokenFlags & TOKEN_HAS_TRAVERSE_PRIVILEGE) @@ -200,6 +202,7 @@ NTAPI SeDeleteAccessState(IN PACCESS_STATE AccessState) { PAUX_ACCESS_DATA AuxData; + PAGED_CODE(); /* Get the Auxiliary Data */ @@ -213,7 +216,8 @@ SeDeleteAccessState(IN PACCESS_STATE AccessState) { ExFreePool(AccessState->ObjectName.Buffer); } - if (AccessState->ObjectTypeName.Buffer) + + if (AccessState->ObjectTypeName.Buffer) { ExFreePool(AccessState->ObjectTypeName.Buffer); } @@ -252,8 +256,9 @@ SeCreateClientSecurity(IN PETHREAD Thread, PACCESS_TOKEN Token; NTSTATUS Status; PACCESS_TOKEN NewToken; + PAGED_CODE(); - + Token = PsReferenceEffectiveToken(Thread, &TokenType, &ThreadEffectiveOnly, @@ -269,7 +274,7 @@ SeCreateClientSecurity(IN PETHREAD Thread, if (Token) ObDereferenceObject(Token); return STATUS_BAD_IMPERSONATION_LEVEL; } - + if ((ImpersonationLevel == SecurityAnonymous) || (ImpersonationLevel == SecurityIdentification) || ((RemoteClient) && (ImpersonationLevel != SecurityDelegation))) @@ -277,12 +282,11 @@ SeCreateClientSecurity(IN PETHREAD Thread, if (Token) ObDereferenceObject(Token); return STATUS_BAD_IMPERSONATION_LEVEL; } - + ClientContext->DirectAccessEffectiveOnly = ((ThreadEffectiveOnly) || - (Qos->EffectiveOnly)) ? - TRUE : FALSE; + (Qos->EffectiveOnly)) ? TRUE : FALSE; } - + if (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING) { ClientContext->DirectlyAccessClientToken = FALSE; @@ -299,10 +303,10 @@ SeCreateClientSecurity(IN PETHREAD Thread, &ClientContext->ClientTokenControl); #endif } - + NewToken = Token; } - + ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); ClientContext->SecurityQos.ImpersonationLevel = Qos->ImpersonationLevel; ClientContext->SecurityQos.ContextTrackingMode = Qos->ContextTrackingMode; @@ -347,9 +351,9 @@ SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext, IN PETHREAD ServerThread OPTIONAL) { UCHAR b; - + PAGED_CODE(); - + if (ClientContext->DirectlyAccessClientToken == FALSE) { b = ClientContext->SecurityQos.EffectiveOnly; @@ -358,10 +362,12 @@ SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext, { b = ClientContext->DirectAccessEffectiveOnly; } + if (ServerThread == NULL) { ServerThread = PsGetCurrentThread(); } + PsImpersonateClient(ServerThread, ClientContext->ClientToken, 1, diff --git a/ntoskrnl/se/acl.c b/ntoskrnl/se/acl.c index 5280ef4a888..35e4a7520e9 100644 --- a/ntoskrnl/se/acl.c +++ b/ntoskrnl/se/acl.c @@ -34,189 +34,188 @@ NTAPI SepInitDACLs(VOID) { ULONG AclLength; - + /* create PublicDefaultDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)); + SePublicDefaultDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicDefaultDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicDefaultDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicDefaultDacl, ACL_REVISION, GENERIC_EXECUTE, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicDefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - - + /* create PublicDefaultUnrestrictedDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + SePublicDefaultUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicDefaultUnrestrictedDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicDefaultUnrestrictedDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_EXECUTE, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid); - + RtlAddAccessAllowedAce(SePublicDefaultUnrestrictedDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, SeRestrictedCodeSid); - + /* create PublicOpenDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + SePublicOpenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicOpenDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicOpenDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicOpenDacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicOpenDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SePublicOpenDacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid); - + /* create PublicOpenUnrestrictedDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + SePublicOpenUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SePublicOpenUnrestrictedDacl == NULL) return FALSE; - + RtlCreateAcl(SePublicOpenUnrestrictedDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeWorldSid); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeAliasAdminsSid); - + RtlAddAccessAllowedAce(SePublicOpenUnrestrictedDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE, SeRestrictedCodeSid); - + /* create SystemDefaultDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + - (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); - + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + SeSystemDefaultDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SeSystemDefaultDacl == NULL) return FALSE; - + RtlCreateAcl(SeSystemDefaultDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SeSystemDefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + RtlAddAccessAllowedAce(SeSystemDefaultDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL, SeAliasAdminsSid); - + /* create UnrestrictedDacl */ AclLength = sizeof(ACL) + - (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + - (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); - + (sizeof(ACE) + RtlLengthSid(SeWorldSid)) + + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)); + SeUnrestrictedDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (SeUnrestrictedDacl == NULL) return FALSE; - + RtlCreateAcl(SeUnrestrictedDacl, AclLength, ACL_REVISION); - + RtlAddAccessAllowedAce(SeUnrestrictedDacl, ACL_REVISION, GENERIC_ALL, SeWorldSid); - + RtlAddAccessAllowedAce(SeUnrestrictedDacl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE, SeRestrictedCodeSid); - - return(TRUE); + + return TRUE; } NTSTATUS NTAPI @@ -226,22 +225,22 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, { ULONG AclLength; PVOID TokenDacl; - + PAGED_CODE(); - + AclLength = sizeof(ACL) + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) + (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) + (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid)); - + TokenDacl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_ACL); if (TokenDacl == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } - + RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION); RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, Token->UserAndGroups->Sid); @@ -251,7 +250,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, SeAliasAdminsSid); RtlAddAccessAllowedAce(TokenDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid); - + /* FIXME */ #if 0 if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL) @@ -260,7 +259,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token, SeRestrictedCodeSid); } #endif - + return STATUS_SUCCESS; } @@ -275,9 +274,9 @@ SepCaptureAcl(IN PACL InputAcl, PACL NewAcl; ULONG AclSize = 0; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + if (AccessMode != KernelMode) { _SEH2_TRY @@ -296,10 +295,10 @@ SepCaptureAcl(IN PACL InputAcl, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + NewAcl = ExAllocatePool(PoolType, AclSize); - if(NewAcl != NULL) + if (NewAcl != NULL) { _SEH2_TRY { @@ -322,23 +321,23 @@ SepCaptureAcl(IN PACL InputAcl, Status = STATUS_INSUFFICIENT_RESOURCES; } } - else if(!CaptureIfKernel) + else if (!CaptureIfKernel) { *CapturedAcl = InputAcl; } else { AclSize = InputAcl->AclSize; - + NewAcl = ExAllocatePool(PoolType, AclSize); - - if(NewAcl != NULL) + + if (NewAcl != NULL) { RtlCopyMemory(NewAcl, InputAcl, AclSize); - + *CapturedAcl = NewAcl; } else @@ -346,7 +345,7 @@ SepCaptureAcl(IN PACL InputAcl, Status = STATUS_INSUFFICIENT_RESOURCES; } } - + return Status; } @@ -357,10 +356,10 @@ SepReleaseAcl(IN PACL CapturedAcl, IN BOOLEAN CaptureIfKernel) { PAGED_CODE(); - - if(CapturedAcl != NULL && - (AccessMode != KernelMode || - (AccessMode == KernelMode && CaptureIfKernel))) + + if (CapturedAcl != NULL && + (AccessMode != KernelMode || + (AccessMode == KernelMode && CaptureIfKernel))) { ExFreePool(CapturedAcl); } diff --git a/ntoskrnl/se/audit.c b/ntoskrnl/se/audit.c index bdd7f93d77a..92b87fa8377 100644 --- a/ntoskrnl/se/audit.c +++ b/ntoskrnl/se/audit.c @@ -4,7 +4,7 @@ * FILE: ntoskrnl/se/audit.c * PURPOSE: Audit functions * - * PROGRAMMERS: Eric Kohl + * PROGRAMMERS: Eric Kohl */ /* INCLUDES *******************************************************************/ @@ -47,6 +47,7 @@ SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject, POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; ULONG ReturnLength = 8; NTSTATUS Status; + PAGED_CODE(); ASSERT(AuditInfo); @@ -120,6 +121,7 @@ SeLocateProcessImageName(IN PEPROCESS Process, PUNICODE_STRING ImageName; PFILE_OBJECT FileObject; NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); /* Assume failure */ @@ -189,7 +191,7 @@ SeAuditHardLinkCreation(IN PUNICODE_STRING FileName, IN PUNICODE_STRING LinkName, IN BOOLEAN bSuccess) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -200,8 +202,8 @@ NTAPI SeAuditingFileEvents(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -213,8 +215,8 @@ SeAuditingFileEventsWithContext(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -225,8 +227,8 @@ NTAPI SeAuditingHardLinkEvents(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -238,8 +240,8 @@ SeAuditingHardLinkEventsWithContext(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -251,8 +253,8 @@ SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -260,13 +262,11 @@ SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted, */ VOID NTAPI -SeCloseObjectAuditAlarm( - IN PVOID Object, +SeCloseObjectAuditAlarm(IN PVOID Object, IN HANDLE Handle, - IN BOOLEAN PerformAction - ) + IN BOOLEAN PerformAction) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -295,10 +295,10 @@ SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName, OUT PBOOLEAN GenerateOnClose) { PAGED_CODE(); - + /* Audits aren't done on kernel-mode access */ if (AccessMode == KernelMode) return; - + /* Otherwise, unimplemented! */ //UNIMPLEMENTED; return; @@ -333,7 +333,7 @@ SePrivilegeObjectAuditAlarm(IN HANDLE Handle, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE CurrentMode) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* SYSTEM CALLS ***************************************************************/ @@ -363,7 +363,7 @@ NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN GenerateOnClose) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -373,7 +373,7 @@ NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN GenerateOnClose) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -392,7 +392,7 @@ NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, OUT PBOOLEAN GenerateOnClose) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -404,7 +404,7 @@ NtPrivilegedServiceAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN AccessGranted) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } @@ -417,7 +417,7 @@ NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, IN BOOLEAN AccessGranted) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } /* EOF */ diff --git a/ntoskrnl/se/lsa.c b/ntoskrnl/se/lsa.c index 15726ad1aa1..b6b36ad6647 100644 --- a/ntoskrnl/se/lsa.c +++ b/ntoskrnl/se/lsa.c @@ -110,8 +110,8 @@ NTSTATUS NTAPI SeMarkLogonSessionForTerminationNotification(IN PLUID LogonId) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* @@ -121,8 +121,8 @@ NTSTATUS NTAPI SeRegisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* @@ -132,8 +132,8 @@ NTSTATUS NTAPI SeUnregisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* EOF */ diff --git a/ntoskrnl/se/priv.c b/ntoskrnl/se/priv.c index d7d3bf95134..603194259e0 100644 --- a/ntoskrnl/se/priv.c +++ b/ntoskrnl/se/priv.c @@ -51,7 +51,7 @@ LUID SeEnableDelegationPrivilege; VOID INIT_FUNCTION NTAPI -SepInitPrivileges (VOID) +SepInitPrivileges(VOID) { SeCreateTokenPrivilege.LowPart = SE_CREATE_TOKEN_PRIVILEGE; SeCreateTokenPrivilege.HighPart = 0; @@ -110,25 +110,25 @@ SepInitPrivileges (VOID) BOOLEAN NTAPI -SepPrivilegeCheck (PTOKEN Token, - PLUID_AND_ATTRIBUTES Privileges, - ULONG PrivilegeCount, - ULONG PrivilegeControl, - KPROCESSOR_MODE PreviousMode) +SepPrivilegeCheck(PTOKEN Token, + PLUID_AND_ATTRIBUTES Privileges, + ULONG PrivilegeCount, + ULONG PrivilegeControl, + KPROCESSOR_MODE PreviousMode) { ULONG i; ULONG j; ULONG k; - - DPRINT ("SepPrivilegeCheck() called\n"); - + + DPRINT("SepPrivilegeCheck() called\n"); + PAGED_CODE(); - + if (PreviousMode == KernelMode) { return TRUE; } - + k = 0; if (PrivilegeCount > 0) { @@ -139,10 +139,10 @@ SepPrivilegeCheck (PTOKEN Token, if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart && Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart) { - DPRINT ("Found privilege\n"); - DPRINT ("Privilege attributes %lx\n", - Token->Privileges[i].Attributes); - + DPRINT("Found privilege\n"); + DPRINT("Privilege attributes %lx\n", + Token->Privileges[i].Attributes); + if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) { Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS; @@ -152,58 +152,58 @@ SepPrivilegeCheck (PTOKEN Token, } } } - + if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) && PrivilegeCount == k) { return TRUE; } - + if (k > 0 && !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY)) { return TRUE; } - + return FALSE; } NTSTATUS NTAPI -SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, - ULONG PrivilegeCount, - KPROCESSOR_MODE PreviousMode, - PLUID_AND_ATTRIBUTES AllocatedMem, - ULONG AllocatedLength, - POOL_TYPE PoolType, - BOOLEAN CaptureIfKernel, - PLUID_AND_ATTRIBUTES* Dest, - PULONG Length) +SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src, + ULONG PrivilegeCount, + KPROCESSOR_MODE PreviousMode, + PLUID_AND_ATTRIBUTES AllocatedMem, + ULONG AllocatedLength, + POOL_TYPE PoolType, + BOOLEAN CaptureIfKernel, + PLUID_AND_ATTRIBUTES *Dest, + PULONG Length) { ULONG BufferSize; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + if (PrivilegeCount == 0) { *Dest = 0; *Length = 0; return STATUS_SUCCESS; } - + if (PreviousMode == KernelMode && !CaptureIfKernel) { *Dest = Src; return STATUS_SUCCESS; } - + /* FIXME - check PrivilegeCount for a valid number so we don't cause an integer overflow or exhaust system resources! */ - + BufferSize = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); *Length = ROUND_UP(BufferSize, 4); /* round up to a 4 byte alignment */ - + /* probe the buffer */ if (PreviousMode != KernelMode) { @@ -220,7 +220,7 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, } _SEH2_END; } - + /* allocate enough memory or check if the provided buffer is large enough to hold the array */ if (AllocatedMem != NULL) @@ -229,14 +229,13 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, { return STATUS_BUFFER_TOO_SMALL; } - + *Dest = AllocatedMem; } else { *Dest = ExAllocatePool(PoolType, BufferSize); - if (*Dest == NULL) { return STATUS_INSUFFICIENT_RESOURCES; @@ -255,23 +254,23 @@ SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + if (!NT_SUCCESS(Status) && AllocatedMem == NULL) { ExFreePool(*Dest); } - + return Status; } VOID NTAPI -SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege, - KPROCESSOR_MODE PreviousMode, - BOOLEAN CaptureIfKernel) +SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege, + KPROCESSOR_MODE PreviousMode, + BOOLEAN CaptureIfKernel) { PAGED_CODE(); - + if (Privilege != NULL && (PreviousMode != KernelMode || CaptureIfKernel)) { @@ -282,39 +281,100 @@ SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege, /* PUBLIC FUNCTIONS ***********************************************************/ /* - * @unimplemented + * @implemented */ NTSTATUS NTAPI -SeAppendPrivileges(PACCESS_STATE AccessState, - PPRIVILEGE_SET Privileges) +SeAppendPrivileges(IN OUT PACCESS_STATE AccessState, + IN PPRIVILEGE_SET Privileges) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} + PAUX_ACCESS_DATA AuxData; + ULONG OldPrivilegeSetSize; + ULONG NewPrivilegeSetSize; + PPRIVILEGE_SET PrivilegeSet; -/* - * @unimplemented - */ -VOID -NTAPI -SeFreePrivileges(IN PPRIVILEGE_SET Privileges) -{ - UNIMPLEMENTED; + PAGED_CODE(); + + /* Get the Auxiliary Data */ + AuxData = AccessState->AuxData; + + /* Calculate the size of the old privilege set */ + OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) + + (AuxData->PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES); + + if (AuxData->PrivilegeSet->PrivilegeCount + + Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT) + { + /* Calculate the size of the new privilege set */ + NewPrivilegeSetSize = OldPrivilegeSetSize + + Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); + + /* Allocate a new privilege set */ + PrivilegeSet = ExAllocatePool(PagedPool, NewPrivilegeSetSize); + if (PrivilegeSet == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + /* Copy original privileges from the acess state */ + RtlCopyMemory(PrivilegeSet, + AuxData->PrivilegeSet, + OldPrivilegeSetSize); + + /* Append privileges from the privilege set*/ + RtlCopyMemory((PVOID)((ULONG_PTR)PrivilegeSet + OldPrivilegeSetSize), + (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)), + Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + + /* Adjust the number of privileges in the new privilege set */ + PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount; + + /* Free the old privilege set if it was allocated */ + if (AccessState->PrivilegesAllocated == TRUE) + ExFreePool(AuxData->PrivilegeSet); + + /* Now we are using an allocated privilege set */ + AccessState->PrivilegesAllocated = TRUE; + + /* Assign the new privileges to the access state */ + AuxData->PrivilegeSet = PrivilegeSet; + } + else + { + /* Append privileges */ + RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegeSet + OldPrivilegeSetSize), + (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)), + Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); + + /* Adjust the number of privileges in the target privilege set */ + AuxData->PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount; + } + + return STATUS_SUCCESS; } /* * @implemented */ -BOOLEAN NTAPI -SePrivilegeCheck (PPRIVILEGE_SET Privileges, - PSECURITY_SUBJECT_CONTEXT SubjectContext, - KPROCESSOR_MODE PreviousMode) +VOID +NTAPI +SeFreePrivileges(IN PPRIVILEGE_SET Privileges) +{ + PAGED_CODE(); + ExFreePool(Privileges); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +SePrivilegeCheck(PPRIVILEGE_SET Privileges, + PSECURITY_SUBJECT_CONTEXT SubjectContext, + KPROCESSOR_MODE PreviousMode) { PACCESS_TOKEN Token = NULL; - + PAGED_CODE(); - + if (SubjectContext->ClientToken == NULL) { Token = SubjectContext->PrimaryToken; @@ -327,58 +387,60 @@ SePrivilegeCheck (PPRIVILEGE_SET Privileges, return FALSE; } } - - return SepPrivilegeCheck (Token, - Privileges->Privilege, - Privileges->PrivilegeCount, - Privileges->Control, - PreviousMode); + + return SepPrivilegeCheck(Token, + Privileges->Privilege, + Privileges->PrivilegeCount, + Privileges->Control, + PreviousMode); } /* * @implemented */ -BOOLEAN NTAPI -SeSinglePrivilegeCheck (IN LUID PrivilegeValue, - IN KPROCESSOR_MODE PreviousMode) +BOOLEAN +NTAPI +SeSinglePrivilegeCheck(IN LUID PrivilegeValue, + IN KPROCESSOR_MODE PreviousMode) { SECURITY_SUBJECT_CONTEXT SubjectContext; PRIVILEGE_SET Priv; BOOLEAN Result; - + PAGED_CODE(); - - SeCaptureSubjectContext (&SubjectContext); - + + SeCaptureSubjectContext(&SubjectContext); + Priv.PrivilegeCount = 1; Priv.Control = PRIVILEGE_SET_ALL_NECESSARY; Priv.Privilege[0].Luid = PrivilegeValue; Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; - - Result = SePrivilegeCheck (&Priv, - &SubjectContext, - PreviousMode); - + + Result = SePrivilegeCheck(&Priv, + &SubjectContext, + PreviousMode); + if (PreviousMode != KernelMode) { #if 0 - SePrivilegedServiceAuditAlarm (0, - &SubjectContext, - &PrivilegeValue); + SePrivilegedServiceAuditAlarm(0, + &SubjectContext, + &PrivilegeValue); #endif } - - SeReleaseSubjectContext (&SubjectContext); - + + SeReleaseSubjectContext(&SubjectContext); + return Result; } /* SYSTEM CALLS ***************************************************************/ -NTSTATUS NTAPI -NtPrivilegeCheck (IN HANDLE ClientToken, - IN PPRIVILEGE_SET RequiredPrivileges, - OUT PBOOLEAN Result) +NTSTATUS +NTAPI +NtPrivilegeCheck(IN HANDLE ClientToken, + IN PPRIVILEGE_SET RequiredPrivileges, + OUT PBOOLEAN Result) { PLUID_AND_ATTRIBUTES Privileges; PTOKEN Token; @@ -388,11 +450,11 @@ NtPrivilegeCheck (IN HANDLE ClientToken, BOOLEAN CheckResult; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = KeGetPreviousMode(); - + /* probe the buffers */ if (PreviousMode != KernelMode) { @@ -402,10 +464,10 @@ NtPrivilegeCheck (IN HANDLE ClientToken, FIELD_OFFSET(PRIVILEGE_SET, Privilege), sizeof(ULONG)); - + PrivilegeCount = RequiredPrivileges->PrivilegeCount; PrivilegeControl = RequiredPrivileges->Control; - + /* Check PrivilegeCount to avoid an integer overflow! */ if (FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]) / @@ -413,13 +475,13 @@ NtPrivilegeCheck (IN HANDLE ClientToken, { _SEH2_YIELD(return STATUS_INVALID_PARAMETER); } - + /* probe all of the array */ ProbeForWrite(RequiredPrivileges, FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]), sizeof(ULONG)); - + ProbeForWriteBoolean(Result); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -434,51 +496,51 @@ NtPrivilegeCheck (IN HANDLE ClientToken, PrivilegeCount = RequiredPrivileges->PrivilegeCount; PrivilegeControl = RequiredPrivileges->Control; } - + /* reference the token and make sure we're not doing an anonymous impersonation */ - Status = ObReferenceObjectByHandle (ClientToken, - TOKEN_QUERY, - SepTokenObjectType, - PreviousMode, - (PVOID*)&Token, - NULL); + Status = ObReferenceObjectByHandle(ClientToken, + TOKEN_QUERY, + SepTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); if (!NT_SUCCESS(Status)) { return Status; } - + if (Token->TokenType == TokenImpersonation && Token->ImpersonationLevel < SecurityIdentification) { - ObDereferenceObject (Token); + ObDereferenceObject(Token); return STATUS_BAD_IMPERSONATION_LEVEL; } - + /* capture the privileges */ - Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege, - PrivilegeCount, - PreviousMode, - NULL, - 0, - PagedPool, - TRUE, - &Privileges, - &Length); + Status = SeCaptureLuidAndAttributesArray(RequiredPrivileges->Privilege, + PrivilegeCount, + PreviousMode, + NULL, + 0, + PagedPool, + TRUE, + &Privileges, + &Length); if (!NT_SUCCESS(Status)) { ObDereferenceObject (Token); return Status; } - - CheckResult = SepPrivilegeCheck (Token, - Privileges, - PrivilegeCount, - PrivilegeControl, - PreviousMode); - - ObDereferenceObject (Token); - + + CheckResult = SepPrivilegeCheck(Token, + Privileges, + PrivilegeCount, + PrivilegeControl, + PreviousMode); + + ObDereferenceObject(Token); + /* return the array */ _SEH2_TRY { @@ -493,13 +555,12 @@ NtPrivilegeCheck (IN HANDLE ClientToken, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - - SeReleaseLuidAndAttributesArray (Privileges, - PreviousMode, - TRUE); - + + SeReleaseLuidAndAttributesArray(Privileges, + PreviousMode, + TRUE); + return Status; } - /* EOF */ diff --git a/ntoskrnl/se/sd.c b/ntoskrnl/se/sd.c index fded835b6af..0e0eadcea36 100644 --- a/ntoskrnl/se/sd.c +++ b/ntoskrnl/se/sd.c @@ -38,79 +38,79 @@ SepInitSDs(VOID) sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicDefaultSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicDefaultSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicDefaultSd, TRUE, SePublicDefaultDacl, FALSE); - + /* Create PublicDefaultUnrestrictedSd */ SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicDefaultUnrestrictedSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, TRUE, SePublicDefaultUnrestrictedDacl, FALSE); - + /* Create PublicOpenSd */ SePublicOpenSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicOpenSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicOpenSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicOpenSd, TRUE, SePublicOpenDacl, FALSE); - + /* Create PublicOpenUnrestrictedSd */ SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicOpenUnrestrictedSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, TRUE, SePublicOpenUnrestrictedDacl, FALSE); - + /* Create SystemDefaultSd */ SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SeSystemDefaultSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SeSystemDefaultSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, TRUE, SeSystemDefaultDacl, FALSE); - + /* Create UnrestrictedSd */ SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SeUnrestrictedSd == NULL) return FALSE; - + RtlCreateSecurityDescriptor(SeUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, TRUE, SeUnrestrictedDacl, FALSE); - + return TRUE; } @@ -125,14 +125,14 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, ULONG SdSize; NTSTATUS Status; PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; - + DPRINT("SeSetWorldSecurityDescriptor() called\n"); - + if (SecurityInformation == 0) { return STATUS_ACCESS_DENIED; } - + /* calculate the minimum size of the buffer */ SidSize = RtlLengthSid(SeWorldSid); SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE); @@ -144,24 +144,24 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, { SdSize += sizeof(ACL) + sizeof(ACE) + SidSize; } - + if (*BufferLength < SdSize) { *BufferLength = SdSize; return STATUS_BUFFER_TOO_SMALL; } - + *BufferLength = SdSize; - + Status = RtlCreateSecurityDescriptorRelative(SdRel, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { return Status; } - + Current = (ULONG_PTR)(SdRel + 1); - + if (SecurityInformation & OWNER_SECURITY_INFORMATION) { RtlCopyMemory((PVOID)Current, @@ -170,7 +170,7 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); Current += SidSize; } - + if (SecurityInformation & GROUP_SECURITY_INFORMATION) { RtlCopyMemory((PVOID)Current, @@ -179,33 +179,33 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); Current += SidSize; } - + if (SecurityInformation & DACL_SECURITY_INFORMATION) { PACL Dacl = (PACL)Current; SdRel->Control |= SE_DACL_PRESENT; - + Status = RtlCreateAcl(Dacl, sizeof(ACL) + sizeof(ACE) + SidSize, ACL_REVISION); if (!NT_SUCCESS(Status)) return Status; - + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SeWorldSid); if (!NT_SUCCESS(Status)) return Status; - + SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel); } - + if (SecurityInformation & SACL_SECURITY_INFORMATION) { /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */ } - + return STATUS_SUCCESS; } @@ -221,37 +221,39 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO { PSECURITY_QUALITY_OF_SERVICE CapturedQos; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + ASSERT(CapturedSecurityQualityOfService); ASSERT(Present); - - if(ObjectAttributes != NULL) + + if (ObjectAttributes != NULL) { - if(AccessMode != KernelMode) + if (AccessMode != KernelMode) { SECURITY_QUALITY_OF_SERVICE SafeQos; - + _SEH2_TRY { ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG)); - if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) { - if(ObjectAttributes->SecurityQualityOfService != NULL) + if (ObjectAttributes->SecurityQualityOfService != NULL) { ProbeForRead(ObjectAttributes->SecurityQualityOfService, sizeof(SECURITY_QUALITY_OF_SERVICE), sizeof(ULONG)); - if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == - sizeof(SECURITY_QUALITY_OF_SERVICE)) + if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == + sizeof(SECURITY_QUALITY_OF_SERVICE)) { - /* don't allocate memory here because ExAllocate should bugcheck - the system if it's buggy, SEH would catch that! So make a local - copy of the qos structure.*/ + /* + * Don't allocate memory here because ExAllocate should bugcheck + * the system if it's buggy, SEH would catch that! So make a local + * copy of the qos structure. + */ RtlCopyMemory(&SafeQos, ObjectAttributes->SecurityQualityOfService, sizeof(SECURITY_QUALITY_OF_SERVICE)); @@ -278,14 +280,14 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO Status = _SEH2_GetExceptionCode(); } _SEH2_END; - - if(NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { - if(*Present) + if (*Present) { CapturedQos = ExAllocatePool(PoolType, sizeof(SECURITY_QUALITY_OF_SERVICE)); - if(CapturedQos != NULL) + if (CapturedQos != NULL) { RtlCopyMemory(CapturedQos, &SafeQos, @@ -305,18 +307,18 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO } else { - if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) + if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) { - if(CaptureIfKernel) + if (CaptureIfKernel) { - if(ObjectAttributes->SecurityQualityOfService != NULL) + if (ObjectAttributes->SecurityQualityOfService != NULL) { - if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == - sizeof(SECURITY_QUALITY_OF_SERVICE)) + if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == + sizeof(SECURITY_QUALITY_OF_SERVICE)) { CapturedQos = ExAllocatePool(PoolType, sizeof(SECURITY_QUALITY_OF_SERVICE)); - if(CapturedQos != NULL) + if (CapturedQos != NULL) { RtlCopyMemory(CapturedQos, ObjectAttributes->SecurityQualityOfService, @@ -357,7 +359,7 @@ SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIO *CapturedSecurityQualityOfService = NULL; *Present = FALSE; } - + return Status; } @@ -369,9 +371,9 @@ SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecur IN BOOLEAN CaptureIfKernel) { PAGED_CODE(); - - if(CapturedSecurityQualityOfService != NULL && - (AccessMode != KernelMode || CaptureIfKernel)) + + if (CapturedSecurityQualityOfService != NULL && + (AccessMode != KernelMode || CaptureIfKernel)) { ExFreePool(CapturedSecurityQualityOfService); } @@ -398,44 +400,48 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, ULONG SaclSize = 0, DaclSize = 0; ULONG DescriptorSize = 0; NTSTATUS Status; - - if(OriginalSecurityDescriptor != NULL) + + if (OriginalSecurityDescriptor != NULL) { - if(CurrentMode != KernelMode) + if (CurrentMode != KernelMode) { RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy)); - + _SEH2_TRY { - /* first only probe and copy until the control field of the descriptor - to determine whether it's a self-relative descriptor */ + /* + * First only probe and copy until the control field of the descriptor + * to determine whether it's a self-relative descriptor + */ DescriptorSize = FIELD_OFFSET(SECURITY_DESCRIPTOR, Owner); ProbeForRead(OriginalSecurityDescriptor, DescriptorSize, sizeof(ULONG)); - - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + + if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { _SEH2_YIELD(return STATUS_UNKNOWN_REVISION); } - - /* make a copy on the stack */ + + /* Make a copy on the stack */ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; DescriptorCopy.Control = OriginalSecurityDescriptor->Control; DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - - /* probe and copy the entire security descriptor structure. The SIDs - and ACLs will be probed and copied later though */ + + /* + * Probe and copy the entire security descriptor structure. The SIDs + * and ACLs will be probed and copied later though + */ ProbeForRead(OriginalSecurityDescriptor, DescriptorSize, sizeof(ULONG)); - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + if (DescriptorCopy.Control & SE_SELF_RELATIVE) { PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; - + DescriptorCopy.Owner = (PSID)RelSD->Owner; DescriptorCopy.Group = (PSID)RelSD->Group; DescriptorCopy.Sacl = (PACL)RelSD->Sacl; @@ -456,33 +462,33 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, } _SEH2_END; } - else if(!CaptureIfKernel) + else if (!CaptureIfKernel) { - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { return STATUS_UNKNOWN_REVISION; } - + *CapturedSecurityDescriptor = OriginalSecurityDescriptor; return STATUS_SUCCESS; } else { - if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) + if (OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { return STATUS_UNKNOWN_REVISION; } - - /* make a copy on the stack */ + + /* Make a copy on the stack */ DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision; DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1; DescriptorCopy.Control = OriginalSecurityDescriptor->Control; DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR)); - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + if (DescriptorCopy.Control & SE_SELF_RELATIVE) { PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor; - + DescriptorCopy.Owner = (PSID)RelSD->Owner; DescriptorCopy.Group = (PSID)RelSD->Group; DescriptorCopy.Sacl = (PACL)RelSD->Sacl; @@ -496,32 +502,34 @@ SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl; } } - - if(DescriptorCopy.Control & SE_SELF_RELATIVE) + + if (DescriptorCopy.Control & SE_SELF_RELATIVE) { - /* in case we're dealing with a self-relative descriptor, do a basic convert - to an absolute descriptor. We do this so we can simply access the data - using the pointers without calculating them again. */ + /* + * In case we're dealing with a self-relative descriptor, do a basic convert + * to an absolute descriptor. We do this so we can simply access the data + * using the pointers without calculating them again. + */ DescriptorCopy.Control &= ~SE_SELF_RELATIVE; - if(DescriptorCopy.Owner != NULL) + if (DescriptorCopy.Owner != NULL) { DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner); } - if(DescriptorCopy.Group != NULL) + if (DescriptorCopy.Group != NULL) { DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group); } - if(DescriptorCopy.Dacl != NULL) + if (DescriptorCopy.Dacl != NULL) { DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl); } - if(DescriptorCopy.Sacl != NULL) + if (DescriptorCopy.Sacl != NULL) { DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl); } } - - /* determine the size of the SIDs */ + + /* Determine the size of the SIDs */ #define DetermineSIDSize(SidType) \ do { \ if(DescriptorCopy.SidType != NULL) \ @@ -530,7 +538,7 @@ SID *SidType = (SID*)DescriptorCopy.SidType; \ \ if(CurrentMode != KernelMode) \ { \ -/* securely access the buffers! */ \ +/* Securely access the buffers! */ \ _SEH2_TRY \ { \ SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \ @@ -555,13 +563,13 @@ DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \ } \ } \ } while(0) - + DetermineSIDSize(Owner); DetermineSIDSize(Group); - + #undef DetermineSIDSize - - /* determine the size of the ACLs */ + + /* Determine the size of the ACLs */ #define DetermineACLSize(AclType, AclFlag) \ do { \ if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \ @@ -571,7 +579,7 @@ PACL AclType = (PACL)DescriptorCopy.AclType; \ \ if(CurrentMode != KernelMode) \ { \ -/* securely access the buffers! */ \ +/* Securely access the buffers! */ \ _SEH2_TRY \ { \ AclType##Size = ProbeForReadUshort(&AclType->AclSize); \ @@ -598,33 +606,37 @@ else \ DescriptorCopy.AclType = NULL; \ } \ } while(0) - + DetermineACLSize(Sacl, SACL); DetermineACLSize(Dacl, DACL); - + #undef DetermineACLSize - - /* allocate enough memory to store a complete copy of a self-relative - security descriptor */ + + /* + * Allocate enough memory to store a complete copy of a self-relative + * security descriptor + */ NewDescriptor = ExAllocatePoolWithTag(PoolType, DescriptorSize, TAG_SD); - if(NewDescriptor != NULL) + if (NewDescriptor != NULL) { ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR); - + RtlZeroMemory(NewDescriptor, DescriptorSize); NewDescriptor->Revision = DescriptorCopy.Revision; NewDescriptor->Sbz1 = DescriptorCopy.Sbz1; NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE; - + _SEH2_TRY { - /* setup the offsets and copy the SIDs and ACLs to the new - self-relative security descriptor. Probing the pointers is not - neccessary anymore as we did that when collecting the sizes! - Make sure to validate the SIDs and ACLs *again* as they could have - been modified in the meanwhile! */ + /* + * Setup the offsets and copy the SIDs and ACLs to the new + * self-relative security descriptor. Probing the pointers is not + * neccessary anymore as we did that when collecting the sizes! + * Make sure to validate the SIDs and ACLs *again* as they could have + * been modified in the meanwhile! + */ #define CopySID(Type) \ do { \ if(DescriptorCopy.Type != NULL) \ @@ -642,12 +654,12 @@ RtlRaiseStatus(STATUS_INVALID_SID); \ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } \ } while(0) - + CopySID(Owner); CopySID(Group); - + #undef CopySID - + #define CopyACL(Type) \ do { \ if(DescriptorCopy.Type != NULL) \ @@ -665,25 +677,26 @@ RtlRaiseStatus(STATUS_INVALID_ACL); \ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } \ } while(0) - + CopyACL(Sacl); CopyACL(Dacl); - + #undef CopyACL } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* we failed to copy the data to the new descriptor */ + /* We failed to copy the data to the new descriptor */ ExFreePool(NewDescriptor); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - - /* we're finally done! copy the pointer to the captured descriptor to - to the caller */ + + /* + * We're finally done! + * Copy the pointer to the captured descriptor to to the caller. + */ *CapturedSecurityDescriptor = NewDescriptor; return STATUS_SUCCESS; - } else { @@ -692,10 +705,10 @@ Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \ } else { - /* nothing to do... */ + /* Nothing to do... */ *CapturedSecurityDescriptor = NULL; } - + return Status; } @@ -721,9 +734,9 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, ULONG Control = 0; ULONG_PTR Current; ULONG SdLength; - + RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; - + if (*ObjectsSecurityDescriptor == NULL) { if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) @@ -731,15 +744,15 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); return STATUS_BUFFER_TOO_SMALL; } - + *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); RtlCreateSecurityDescriptorRelative(RelSD, SECURITY_DESCRIPTOR_REVISION); return STATUS_SUCCESS; } - + ObjectSd = *ObjectsSecurityDescriptor; - + /* Calculate the required security descriptor length */ Control = SE_SELF_RELATIVE; if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) && @@ -749,7 +762,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); } - + if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) && (ObjectSd->Group != NULL)) { @@ -757,7 +770,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, GroupLength = ROUND_UP(RtlLengthSid(Group), 4); Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); } - + if ((*SecurityInformation & DACL_SECURITY_INFORMATION) && (ObjectSd->Control & SE_DACL_PRESENT)) { @@ -766,9 +779,10 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } - + if ((*SecurityInformation & SACL_SECURITY_INFORMATION) && (ObjectSd->Control & SE_SACL_PRESENT)) { @@ -777,9 +791,10 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); SaclLength = ROUND_UP(Sacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } - + SdLength = OwnerLength + GroupLength + DaclLength + SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE); if (*Length < SdLength) @@ -787,14 +802,14 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, *Length = SdLength; return STATUS_BUFFER_TOO_SMALL; } - + /* Build the new security descrtiptor */ RtlCreateSecurityDescriptorRelative(RelSD, SECURITY_DESCRIPTOR_REVISION); RelSD->Control = (USHORT)Control; - + Current = (ULONG_PTR)(RelSD + 1); - + if (OwnerLength != 0) { RtlCopyMemory((PVOID)Current, @@ -803,7 +818,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += OwnerLength; } - + if (GroupLength != 0) { RtlCopyMemory((PVOID)Current, @@ -812,7 +827,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += GroupLength; } - + if (DaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -821,7 +836,7 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += DaclLength; } - + if (SaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -830,9 +845,9 @@ SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); Current += SaclLength; } - + *Length = SdLength; - + return STATUS_SUCCESS; } @@ -846,18 +861,20 @@ SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, IN BOOLEAN CaptureIfKernelMode) { PAGED_CODE(); - - /* WARNING! You need to call this function with the same value for CurrentMode - and CaptureIfKernelMode that you previously passed to - SeCaptureSecurityDescriptor() in order to avoid memory leaks! */ - if(CapturedSecurityDescriptor != NULL && - (CurrentMode != KernelMode || - (CurrentMode == KernelMode && CaptureIfKernelMode))) + + /* + * WARNING! You need to call this function with the same value for CurrentMode + * and CaptureIfKernelMode that you previously passed to + * SeCaptureSecurityDescriptor() in order to avoid memory leaks! + */ + if (CapturedSecurityDescriptor != NULL && + (CurrentMode != KernelMode || + (CurrentMode == KernelMode && CaptureIfKernelMode))) { - /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ + /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD); } - + return STATUS_SUCCESS; } @@ -886,26 +903,28 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, ULONG Control = 0; ULONG_PTR Current; SECURITY_INFORMATION SecurityInformation; - + ObjectSd = *ObjectsSecurityDescriptor; - + + /* The object does not have a security descriptor. */ if (!ObjectSd) - return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. - + return STATUS_NO_SECURITY_ON_OBJECT; + SecurityInformation = *_SecurityInformation; - + /* Get owner and owner size */ if (SecurityInformation & OWNER_SECURITY_INFORMATION) { if (SecurityDescriptor->Owner != NULL) { - if( SecurityDescriptor->Control & SE_SELF_RELATIVE ) + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner + (ULONG_PTR)SecurityDescriptor); else Owner = (PSID)SecurityDescriptor->Owner; OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); } + Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED); } else @@ -915,6 +934,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd); OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); } + Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); } @@ -930,6 +950,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Group = (PSID)SecurityDescriptor->Group; GroupLength = ROUND_UP(RtlLengthSid(Group), 4); } + Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED); } else @@ -939,9 +960,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd); GroupLength = ROUND_UP(RtlLengthSid(Group), 4); } + Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); } - + /* Get DACL and DACL size */ if (SecurityInformation & DACL_SECURITY_INFORMATION) { @@ -953,9 +975,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, (ULONG_PTR)SecurityDescriptor); else Dacl = (PACL)SecurityDescriptor->Dacl; - + DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); } + Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } else @@ -966,6 +989,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); } @@ -982,6 +1006,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Sacl = (PACL)SecurityDescriptor->Sacl; SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4); } + Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } else @@ -992,9 +1017,10 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4); } + Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); } - + NewSd = ExAllocatePool(NonPagedPool, sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength + DaclLength + SaclLength); @@ -1003,14 +1029,15 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, ObDereferenceObject(Object); return STATUS_INSUFFICIENT_RESOURCES; } - + RtlCreateSecurityDescriptor(NewSd, SECURITY_DESCRIPTOR_REVISION1); + /* We always build a self-relative descriptor */ NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE; - + Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR); - + if (OwnerLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1019,7 +1046,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd); Current += OwnerLength; } - + if (GroupLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1028,7 +1055,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd); Current += GroupLength; } - + if (DaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1037,7 +1064,7 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd); Current += DaclLength; } - + if (SaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1045,8 +1072,8 @@ SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, SaclLength); NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd); Current += SaclLength; - } - + } + *ObjectsSecurityDescriptor = NewSd; return STATUS_SUCCESS; } @@ -1065,12 +1092,13 @@ SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL, IN PGENERIC_MAPPING GenericMapping) { PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor; - + + /* The object does not have a security descriptor. */ if (!ObjectSd) - return STATUS_NO_SECURITY_ON_OBJECT; // The object does not have a security descriptor. - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + return STATUS_NO_SECURITY_ON_OBJECT; + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } @@ -1085,54 +1113,54 @@ SeValidSecurityDescriptor(IN ULONG Length, PISID Sid; PACL Acl; PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; - + if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH) { DPRINT1("Invalid Security Descriptor revision\n"); return FALSE; } - + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) { DPRINT1("Invalid Security Descriptor revision\n"); return FALSE; } - + if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE)) { DPRINT1("No self-relative Security Descriptor\n"); return FALSE; } - + SdLength = sizeof(SECURITY_DESCRIPTOR); - + /* Check Owner SID */ if (SecurityDescriptor->Owner == NULL) { DPRINT1("No Owner SID\n"); return FALSE; } - + if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG)) { DPRINT1("Invalid Owner SID alignment\n"); return FALSE; } - + Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner); if (Sid->Revision != SID_REVISION) { DPRINT1("Invalid Owner SID revision\n"); return FALSE; } - + SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); if (Length < SdLength) { DPRINT1("Invalid Owner SID size\n"); return FALSE; } - + /* Check Group SID */ if (SecurityDescriptor->Group != NULL) { @@ -1141,14 +1169,14 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid Group SID alignment\n"); return FALSE; } - + Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group); if (Sid->Revision != SID_REVISION) { DPRINT1("Invalid Group SID revision\n"); return FALSE; } - + SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); if (Length < SdLength) { @@ -1156,7 +1184,7 @@ SeValidSecurityDescriptor(IN ULONG Length, return FALSE; } } - + /* Check DACL */ if (SecurityDescriptor->Dacl != NULL) { @@ -1165,7 +1193,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid DACL alignment\n"); return FALSE; } - + Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl); if ((Acl->AclRevision < MIN_ACL_REVISION) && (Acl->AclRevision > MAX_ACL_REVISION)) @@ -1173,7 +1201,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid DACL revision\n"); return FALSE; } - + SdLength += Acl->AclSize; if (Length < SdLength) { @@ -1181,7 +1209,7 @@ SeValidSecurityDescriptor(IN ULONG Length, return FALSE; } } - + /* Check SACL */ if (SecurityDescriptor->Sacl != NULL) { @@ -1190,7 +1218,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid SACL alignment\n"); return FALSE; } - + Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl); if ((Acl->AclRevision < MIN_ACL_REVISION) || (Acl->AclRevision > MAX_ACL_REVISION)) @@ -1198,7 +1226,7 @@ SeValidSecurityDescriptor(IN ULONG Length, DPRINT1("Invalid SACL revision\n"); return FALSE; } - + SdLength += Acl->AclSize; if (Length < SdLength) { @@ -1206,7 +1234,7 @@ SeValidSecurityDescriptor(IN ULONG Length, return FALSE; } } - + return TRUE; } @@ -1217,13 +1245,13 @@ NTSTATUS NTAPI SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor) { PAGED_CODE(); - + if (*SecurityDescriptor != NULL) { ExFreePool(*SecurityDescriptor); *SecurityDescriptor = NULL; } - + return STATUS_SUCCESS; } @@ -1273,12 +1301,12 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, PSID Group = NULL; PACL Dacl = NULL; PACL Sacl = NULL; - + PAGED_CODE(); - + /* Lock subject context */ SeLockSubjectContext(SubjectContext); - + if (SubjectContext->ClientToken != NULL) { Token = SubjectContext->ClientToken; @@ -1287,18 +1315,16 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Token = SubjectContext->PrimaryToken; } - - + /* Inherit the Owner SID */ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Owner != NULL) { DPRINT("Use explicit owner sid!\n"); Owner = ExplicitDescriptor->Owner; - + if (ExplicitDescriptor->Control & SE_SELF_RELATIVE) { Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor); - } } else @@ -1313,13 +1339,12 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, DPRINT("Use default owner sid!\n"); Owner = SeLocalSystemSid; } - + Control |= SE_OWNER_DEFAULTED; } - + OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); - - + /* Inherit the Group SID */ if (ExplicitDescriptor != NULL && ExplicitDescriptor->Group != NULL) { @@ -1342,13 +1367,12 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, DPRINT("Use default group sid!\n"); Group = SeLocalSystemSid; } - + Control |= SE_OWNER_DEFAULTED; } - + GroupLength = ROUND_UP(RtlLengthSid(Group), 4); - - + /* Inherit the DACL */ if (ExplicitDescriptor != NULL && (ExplicitDescriptor->Control & SE_DACL_PRESENT) && @@ -1360,7 +1384,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ExplicitDescriptor); } - + Control |= SE_DACL_PRESENT; } else if (ParentDescriptor != NULL && @@ -1373,6 +1397,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Dacl = (PACL)(((ULONG_PTR)Dacl) + (ULONG_PTR)ParentDescriptor); } + Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); } else if (Token != NULL && Token->DefaultDacl != NULL) @@ -1388,10 +1413,9 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, Dacl = NULL; Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); } - + DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0; - - + /* Inherit the SACL */ if (ExplicitDescriptor != NULL && (ExplicitDescriptor->Control & SE_SACL_PRESENT) && @@ -1403,7 +1427,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ExplicitDescriptor); } - + Control |= SE_SACL_PRESENT; } else if (ParentDescriptor != NULL && @@ -1416,23 +1440,23 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, { Sacl = (PACL)(((ULONG_PTR)Sacl) + (ULONG_PTR)ParentDescriptor); } + Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED); } - + SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0; - - + /* Allocate and initialize the new security descriptor */ Length = sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength + DaclLength + SaclLength; - + DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n", sizeof(SECURITY_DESCRIPTOR), OwnerLength, GroupLength, DaclLength, SaclLength); - + Descriptor = ExAllocatePoolWithTag(PagedPool, Length, TAG_SD); @@ -1442,15 +1466,15 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, /* FIXME: Unlock subject context */ return STATUS_INSUFFICIENT_RESOURCES; } - + RtlZeroMemory( Descriptor, Length ); RtlCreateSecurityDescriptor(Descriptor, SECURITY_DESCRIPTOR_REVISION); - + Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE; - + Current = (ULONG_PTR)Descriptor + sizeof(SECURITY_DESCRIPTOR); - + if (SaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1459,7 +1483,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, Descriptor->Sacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); Current += SaclLength; } - + if (DaclLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1468,7 +1492,7 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, Descriptor->Dacl = (PACL)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); Current += DaclLength; } - + if (OwnerLength != 0) { RtlCopyMemory((PVOID)Current, @@ -1479,8 +1503,10 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner); } else + { DPRINT("Owner of %x is zero length\n", Descriptor); - + } + if (GroupLength != 0) { memmove((PVOID)Current, @@ -1488,15 +1514,15 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, GroupLength); Descriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)Descriptor); } - + /* Unlock subject context */ SeUnlockSubjectContext(SubjectContext); - + *NewDescriptor = Descriptor; - + DPRINT("Descrptor %x\n", Descriptor); ASSERT(RtlLengthSecurityDescriptor(Descriptor)); - + return STATUS_SUCCESS; } diff --git a/ntoskrnl/se/semgr.c b/ntoskrnl/se/semgr.c index de374473139..406003b0af9 100644 --- a/ntoskrnl/se/semgr.c +++ b/ntoskrnl/se/semgr.c @@ -17,13 +17,15 @@ PSE_EXPORTS SeExports = NULL; SE_EXPORTS SepExports; +ULONG SidInTokenCalls = 0; extern ULONG ExpInitializationPhase; extern ERESOURCE SepSubjectContextLock; /* PRIVATE FUNCTIONS **********************************************************/ -static BOOLEAN INIT_FUNCTION +static BOOLEAN +INIT_FUNCTION SepInitExports(VOID) { SepExports.SeCreateTokenPrivilege = SeCreateTokenPrivilege; @@ -118,6 +120,7 @@ NTAPI SepInitializationPhase1(VOID) { NTSTATUS Status; + PAGED_CODE(); /* Insert the system token into the tree */ @@ -279,8 +282,6 @@ SeDefaultObjectMethod(IN PVOID Object, return STATUS_SUCCESS; } -ULONG SidInTokenCalls = 0; - static BOOLEAN SepSidInToken(PACCESS_TOKEN _Token, PSID Sid) @@ -292,7 +293,7 @@ SepSidInToken(PACCESS_TOKEN _Token, SidInTokenCalls++; if (!(SidInTokenCalls % 10000)) DPRINT1("SidInToken Calls: %d\n", SidInTokenCalls); - + if (Token->UserAndGroupCount == 0) { return FALSE; @@ -340,7 +341,8 @@ SepTokenIsOwner(PACCESS_TOKEN Token, return SepSidInToken(Token, Sid); } -VOID NTAPI +VOID +NTAPI SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, OUT PACCESS_MASK DesiredAccess) { @@ -351,13 +353,15 @@ SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, { *DesiredAccess |= READ_CONTROL; } + if (SecurityInformation & SACL_SECURITY_INFORMATION) { *DesiredAccess |= ACCESS_SYSTEM_SECURITY; } } -VOID NTAPI +VOID +NTAPI SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, OUT PACCESS_MASK DesiredAccess) { @@ -367,10 +371,12 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, { *DesiredAccess |= WRITE_OWNER; } + if (SecurityInformation & DACL_SECURITY_INFORMATION) { *DesiredAccess |= WRITE_DAC; } + if (SecurityInformation & SACL_SECURITY_INFORMATION) { *DesiredAccess |= ACCESS_SYSTEM_SECURITY; @@ -494,7 +500,7 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, { *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; } - + *AccessStatus = STATUS_SUCCESS; return TRUE; } @@ -763,7 +769,8 @@ SepGetSDGroup(IN PSECURITY_DESCRIPTOR _SecurityDescriptor) /* * @implemented */ -BOOLEAN NTAPI +BOOLEAN +NTAPI SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN BOOLEAN SubjectContextLocked, diff --git a/ntoskrnl/se/sid.c b/ntoskrnl/se/sid.c index d70a743135a..93b8bde6d16 100644 --- a/ntoskrnl/se/sid.c +++ b/ntoskrnl/se/sid.c @@ -99,11 +99,11 @@ SepInitSecurityIDs(VOID) ULONG SidLength1; ULONG SidLength2; PULONG SubAuthority; - + SidLength0 = RtlLengthRequiredSid(0); SidLength1 = RtlLengthRequiredSid(1); SidLength2 = RtlLengthRequiredSid(2); - + /* create NullSid */ SeNullSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); SeWorldSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); @@ -150,9 +150,9 @@ SepInitSecurityIDs(VOID) SeAnonymousLogonSid == NULL) { FreeInitializedSids(); - return(FALSE); + return FALSE; } - + RtlInitializeSid(SeNullSid, &SeNullSidAuthority, 1); RtlInitializeSid(SeWorldSid, &SeWorldSidAuthority, 1); RtlInitializeSid(SeLocalSid, &SeLocalSidAuthority, 1); @@ -181,7 +181,7 @@ SepInitSecurityIDs(VOID) RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1); RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1); RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1); - + SubAuthority = RtlSubAuthoritySid(SeNullSid, 0); *SubAuthority = SECURITY_NULL_RID; SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0); @@ -252,8 +252,8 @@ SepInitSecurityIDs(VOID) *SubAuthority = SECURITY_RESTRICTED_CODE_RID; SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0); *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID; - - return(TRUE); + + return TRUE; } NTSTATUS @@ -267,9 +267,9 @@ SepCaptureSid(IN PSID InputSid, ULONG SidSize = 0; PISID NewSid, Sid = (PISID)InputSid; NTSTATUS Status; - + PAGED_CODE(); - + if (AccessMode != KernelMode) { _SEH2_TRY @@ -289,11 +289,11 @@ SepCaptureSid(IN PSID InputSid, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + /* allocate a SID and copy it */ NewSid = ExAllocatePool(PoolType, SidSize); - if(NewSid != NULL) + if (NewSid != NULL) { _SEH2_TRY { @@ -316,7 +316,7 @@ SepCaptureSid(IN PSID InputSid, Status = STATUS_INSUFFICIENT_RESOURCES; } } - else if(!CaptureIfKernel) + else if (!CaptureIfKernel) { *CapturedSid = InputSid; return STATUS_SUCCESS; @@ -324,16 +324,16 @@ SepCaptureSid(IN PSID InputSid, else { SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); - + /* allocate a SID and copy it */ NewSid = ExAllocatePool(PoolType, SidSize); - if(NewSid != NULL) + if (NewSid != NULL) { RtlCopyMemory(NewSid, Sid, SidSize); - + *CapturedSid = NewSid; } else @@ -341,7 +341,7 @@ SepCaptureSid(IN PSID InputSid, Status = STATUS_INSUFFICIENT_RESOURCES; } } - + return Status; } @@ -352,10 +352,10 @@ SepReleaseSid(IN PSID CapturedSid, IN BOOLEAN CaptureIfKernel) { PAGED_CODE(); - - if(CapturedSid != NULL && - (AccessMode != KernelMode || - (AccessMode == KernelMode && CaptureIfKernel))) + + if (CapturedSid != NULL && + (AccessMode != KernelMode || + (AccessMode == KernelMode && CaptureIfKernel))) { ExFreePool(CapturedSid); } diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c index 8f73312fde4..6ee52544ba4 100644 --- a/ntoskrnl/se/token.c +++ b/ntoskrnl/se/token.c @@ -25,16 +25,18 @@ ERESOURCE SepTokenLock; TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}}; LUID SeSystemAuthenticationId = SYSTEM_LUID; -static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ, +static GENERIC_MAPPING SepTokenMapping = { + TOKEN_READ, TOKEN_WRITE, TOKEN_EXECUTE, -TOKEN_ALL_ACCESS}; + TOKEN_ALL_ACCESS +}; static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = { - + /* Class 0 not used, blame M$! */ ICI_SQ_SAME( 0, 0, 0), - + /* TokenUser */ ICI_SQ_SAME( sizeof(TOKEN_USER), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ), /* TokenGroups */ @@ -79,11 +81,11 @@ SepCompareTokens(IN PTOKEN FirstToken, OUT PBOOLEAN Equal) { BOOLEAN Restricted, IsEqual = FALSE; - + ASSERT(FirstToken != SecondToken); - + /* FIXME: Check if every SID that is present in either token is also present in the other one */ - + Restricted = SeTokenIsRestricted(FirstToken); if (Restricted == SeTokenIsRestricted(SecondToken)) { @@ -91,10 +93,10 @@ SepCompareTokens(IN PTOKEN FirstToken, { /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */ } - + /* FIXME: Check if every privilege that is present in either token is also present in the other one */ } - + *Equal = IsEqual; return STATUS_SUCCESS; } @@ -108,10 +110,11 @@ SepFreeProxyData(PVOID ProxyData) NTSTATUS NTAPI -SepCopyProxyData(PVOID* Dest, PVOID Src) +SepCopyProxyData(PVOID* Dest, + PVOID Src) { UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return STATUS_NOT_IMPLEMENTED; } NTSTATUS @@ -122,24 +125,24 @@ SeExchangePrimaryToken(PEPROCESS Process, { PTOKEN OldToken; PTOKEN NewToken = (PTOKEN)NewTokenP; - + PAGED_CODE(); - + if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE); if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE); - + /* Mark new token in use */ NewToken->TokenInUse = 1; - + /* Reference the New Token */ ObReferenceObject(NewToken); - + /* Replace the old with the new */ OldToken = ObFastReplaceObject(&Process->Token, NewToken); - + /* Mark the Old Token as free */ OldToken->TokenInUse = 0; - + *OldTokenP = (PACCESS_TOKEN)OldToken; return STATUS_SUCCESS; } @@ -149,10 +152,10 @@ NTAPI SeDeassignPrimaryToken(PEPROCESS Process) { PTOKEN OldToken; - + /* Remove the Token */ OldToken = ObFastReplaceObject(&Process->Token, NULL); - + /* Mark the Old Token as free */ OldToken->TokenInUse = 0; } @@ -163,14 +166,14 @@ RtlLengthSidAndAttributes(ULONG Count, { ULONG i; ULONG uLength; - + PAGED_CODE(); - + uLength = Count * sizeof(SID_AND_ATTRIBUTES); for (i = 0; i < Count; i++) uLength += RtlLengthSid(Src[i].Sid); - - return(uLength); + + return uLength; } @@ -181,14 +184,14 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token, PSID DefaultOwner) { ULONG i; - + Token->PrimaryGroup = 0; - + if (DefaultOwner) { Token->DefaultOwnerIndex = Token->UserAndGroupCount; } - + /* Validate and set the primary group and user pointers */ for (i = 0; i < Token->UserAndGroupCount; i++) { @@ -197,24 +200,24 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token, { Token->DefaultOwnerIndex = i; } - + if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup)) { Token->PrimaryGroup = Token->UserAndGroups[i].Sid; } } - + if (Token->DefaultOwnerIndex == Token->UserAndGroupCount) { return(STATUS_INVALID_OWNER); } - + if (Token->PrimaryGroup == 0) { return(STATUS_INVALID_PRIMARY_GROUP); } - - return(STATUS_SUCCESS); + + return STATUS_SUCCESS; } @@ -233,9 +236,9 @@ SepDuplicateToken(PTOKEN Token, PVOID EndMem; PTOKEN AccessToken; NTSTATUS Status; - + PAGED_CODE(); - + Status = ObCreateObject(PreviousMode, SepTokenObjectType, ObjectAttributes, @@ -248,7 +251,7 @@ SepDuplicateToken(PTOKEN Token, if (!NT_SUCCESS(Status)) { DPRINT1("ObCreateObject() failed (Status %lx)\n", Status); - return(Status); + return Status; } /* Zero out the buffer */ @@ -258,22 +261,22 @@ SepDuplicateToken(PTOKEN Token, if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken); - return(Status); + return Status; } - + Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId); if (!NT_SUCCESS(Status)) { ObDereferenceObject(AccessToken); - return(Status); + return Status; } - + AccessToken->TokenLock = &SepTokenLock; - + AccessToken->TokenType = TokenType; AccessToken->ImpersonationLevel = Level; RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId); - + AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart; AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart; memcpy(AccessToken->TokenSource.SourceName, @@ -282,18 +285,18 @@ SepDuplicateToken(PTOKEN Token, AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart; AccessToken->UserAndGroupCount = Token->UserAndGroupCount; AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex; - + uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; for (i = 0; i < Token->UserAndGroupCount; i++) uLength += RtlLengthSid(Token->UserAndGroups[i].Sid); - + AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'uKOT'); - + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - + Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount, Token->UserAndGroups, uLength, @@ -308,17 +311,17 @@ SepDuplicateToken(PTOKEN Token, Token->PrimaryGroup, 0); } - + if (NT_SUCCESS(Status)) { AccessToken->PrivilegeCount = Token->PrivilegeCount; - + uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); AccessToken->Privileges = (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'pKOT'); - + for (i = 0; i < AccessToken->PrivilegeCount; i++) { RtlCopyLuid(&AccessToken->Privileges[i].Luid, @@ -326,8 +329,8 @@ SepDuplicateToken(PTOKEN Token, AccessToken->Privileges[i].Attributes = Token->Privileges[i].Attributes; } - - if ( Token->DefaultDacl ) + + if (Token->DefaultDacl) { AccessToken->DefaultDacl = (PACL) ExAllocatePoolWithTag(PagedPool, @@ -338,14 +341,14 @@ SepDuplicateToken(PTOKEN Token, Token->DefaultDacl->AclSize); } } - - if ( NT_SUCCESS(Status) ) + + if (NT_SUCCESS(Status)) { *NewAccessToken = AccessToken; return(STATUS_SUCCESS); } - - return(Status); + + return Status; } NTSTATUS @@ -358,7 +361,7 @@ SeSubProcessToken(IN PTOKEN ParentToken, PTOKEN NewToken; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; - + /* Initialize the attributes and duplicate it */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = SepDuplicateToken(ParentToken, @@ -382,12 +385,12 @@ SeSubProcessToken(IN PTOKEN ParentToken, /* Set the session ID */ NewToken->SessionId = SessionId; NewToken->TokenInUse = InUse; - + /* Return the token */ *Token = NewToken; } } - + /* Return status */ return Status; } @@ -399,25 +402,25 @@ SeIsTokenChild(IN PTOKEN Token, { PTOKEN ProcessToken; LUID ProcessLuid, CallerLuid; - + /* Assume failure */ *IsChild = FALSE; - + /* Reference the process token */ ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess()); - + /* Get the ID */ ProcessLuid = ProcessToken->TokenId; - + /* Dereference the token */ ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken); - + /* Get our LUID */ CallerLuid = Token->TokenId; - + /* Compare the LUIDs */ if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE; - + /* Return success */ return STATUS_SUCCESS; } @@ -431,9 +434,9 @@ SeCopyClientToken(IN PACCESS_TOKEN Token, { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; - + PAGED_CODE(); - + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, @@ -446,21 +449,22 @@ SeCopyClientToken(IN PACCESS_TOKEN Token, Level, PreviousMode, (PTOKEN*)NewToken); - - return(Status); + + return Status; } -VOID NTAPI +VOID +NTAPI SepDeleteToken(PVOID ObjectBody) { PTOKEN AccessToken = (PTOKEN)ObjectBody; - + if (AccessToken->UserAndGroups) ExFreePool(AccessToken->UserAndGroups); - + if (AccessToken->Privileges) ExFreePool(AccessToken->Privileges); - + if (AccessToken->DefaultDacl) ExFreePool(AccessToken->DefaultDacl); } @@ -473,12 +477,12 @@ SepInitializeTokenImplementation(VOID) { UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - + ExInitializeResource(&SepTokenLock); - + DPRINT("Creating Token Object Type\n"); - - /* Initialize the Token type */ + + /* Initialize the Token type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Token"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); @@ -499,14 +503,14 @@ SeAssignPrimaryToken(IN PEPROCESS Process, IN PTOKEN Token) { PAGED_CODE(); - + /* Sanity checks */ ASSERT(Token->TokenType == TokenPrimary); ASSERT(!Token->TokenInUse); - + /* Clean any previous token */ if (Process->Token.Object) SeDeassignPrimaryToken(Process); - + /* Set the new token */ ObReferenceObject(Token); Token->TokenInUse = TRUE; @@ -517,25 +521,25 @@ SeAssignPrimaryToken(IN PEPROCESS Process, NTSTATUS NTAPI SepCreateToken(OUT PHANDLE TokenHandle, - IN KPROCESSOR_MODE PreviousMode, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN TOKEN_TYPE TokenType, - IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, - IN PLUID AuthenticationId, - IN PLARGE_INTEGER ExpirationTime, - IN PSID_AND_ATTRIBUTES User, - IN ULONG GroupCount, - IN PSID_AND_ATTRIBUTES Groups, - IN ULONG GroupLength, - IN ULONG PrivilegeCount, - IN PLUID_AND_ATTRIBUTES Privileges, - IN PSID Owner, - IN PSID PrimaryGroup, - IN PACL DefaultDacl, - IN PTOKEN_SOURCE TokenSource, - IN BOOLEAN SystemToken) -{ + IN KPROCESSOR_MODE PreviousMode, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN TOKEN_TYPE TokenType, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN PLUID AuthenticationId, + IN PLARGE_INTEGER ExpirationTime, + IN PSID_AND_ATTRIBUTES User, + IN ULONG GroupCount, + IN PSID_AND_ATTRIBUTES Groups, + IN ULONG GroupLength, + IN ULONG PrivilegeCount, + IN PLUID_AND_ATTRIBUTES Privileges, + IN PSID Owner, + IN PSID PrimaryGroup, + IN PACL DefaultDacl, + IN PTOKEN_SOURCE TokenSource, + IN BOOLEAN SystemToken) +{ PTOKEN AccessToken; LUID TokenId; LUID ModifiedId; @@ -544,7 +548,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, ULONG i; NTSTATUS Status; ULONG TokenFlags = 0; - + /* Loop all groups */ for (i = 0; i < GroupCount; i++) { @@ -554,7 +558,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, /* Force them to be enabled */ Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT); } - + /* Check of the group is an admin group */ if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid)) { @@ -562,7 +566,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, TokenFlags |= TOKEN_HAS_ADMIN_GROUP; } } - + /* Loop all privileges */ for (i = 0; i < PrivilegeCount; i++) { @@ -577,12 +581,12 @@ SepCreateToken(OUT PHANDLE TokenHandle, Status = ZwAllocateLocallyUniqueId(&TokenId); if (!NT_SUCCESS(Status)) - return(Status); - + return Status; + Status = ZwAllocateLocallyUniqueId(&ModifiedId); if (!NT_SUCCESS(Status)) - return(Status); - + return Status; + Status = ObCreateObject(PreviousMode, SepTokenObjectType, ObjectAttributes, @@ -595,50 +599,50 @@ SepCreateToken(OUT PHANDLE TokenHandle, if (!NT_SUCCESS(Status)) { DPRINT1("ObCreateObject() failed (Status %lx)\n"); - return(Status); + return Status; } /* Zero out the buffer */ RtlZeroMemory(AccessToken, sizeof(TOKEN)); - + AccessToken->TokenLock = &SepTokenLock; - + RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier, &TokenSource->SourceIdentifier); memcpy(AccessToken->TokenSource.SourceName, TokenSource->SourceName, sizeof(TokenSource->SourceName)); - + RtlCopyLuid(&AccessToken->TokenId, &TokenId); RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId); AccessToken->ExpirationTime = *ExpirationTime; RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId); - + AccessToken->UserAndGroupCount = GroupCount + 1; AccessToken->PrivilegeCount = PrivilegeCount; - + AccessToken->TokenFlags = TokenFlags; AccessToken->TokenType = TokenType; AccessToken->ImpersonationLevel = ImpersonationLevel; - + /* * Normally we would just point these members into the variable information * area; however, our ObCreateObject() call can't allocate a variable information * area, so we allocate them seperately and provide a destroy function. */ - + uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; uLength += RtlLengthSid(User); for (i = 0; i < GroupCount; i++) uLength += RtlLengthSid(Groups[i].Sid); - + AccessToken->UserAndGroups = (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'uKOT'); - + EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount]; - + Status = RtlCopySidAndAttributesArray(1, User, uLength, @@ -656,7 +660,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, &EndMem, &uLength); } - + if (NT_SUCCESS(Status)) { Status = SepFindPrimaryGroupAndDefaultOwner( @@ -664,7 +668,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, PrimaryGroup, Owner); } - + if (NT_SUCCESS(Status)) { uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); @@ -672,7 +676,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool, uLength, 'pKOT'); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -694,7 +698,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); } } - + if (NT_SUCCESS(Status)) { AccessToken->DefaultDacl = @@ -705,16 +709,15 @@ SepCreateToken(OUT PHANDLE TokenHandle, DefaultDacl, DefaultDacl->AclSize); } - + if (!SystemToken) { - - Status = ObInsertObject ((PVOID)AccessToken, - NULL, - DesiredAccess, - 0, - NULL, - TokenHandle); + Status = ObInsertObject((PVOID)AccessToken, + NULL, + DesiredAccess, + 0, + NULL, + TokenHandle); if (!NT_SUCCESS(Status)) { DPRINT1("ObInsertObject() failed (Status %lx)\n", Status); @@ -745,24 +748,24 @@ SepCreateSystemProcessToken(VOID) ULONG i; PTOKEN Token; NTSTATUS Status; - + /* Don't ever expire */ Expiration.QuadPart = -1; - + /* All groups mandatory and enabled */ GroupAttributes = SE_GROUP_ENABLED | SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT; OwnerAttributes = SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_ENABLED_BY_DEFAULT; - + /* User is system */ UserSid.Sid = SeLocalSystemSid; UserSid.Attributes = 0; - + /* Primary group is local system */ PrimaryGroup = SeLocalSystemSid; - + /* Owner is admins */ Owner = SeAliasAdminsSid; - + /* Groups are admins, world, and authenticated users */ Groups[0].Sid = SeAliasAdminsSid; Groups[0].Attributes = OwnerAttributes; @@ -780,69 +783,69 @@ SepCreateSystemProcessToken(VOID) i = 0; Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeTcbPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeCreateTokenPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeTakeOwnershipPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeCreatePagefilePrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeLockMemoryPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeIncreaseQuotaPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeCreatePermanentPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeDebugPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeAuditPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSecurityPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSystemEnvironmentPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeChangeNotifyPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeBackupPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeRestorePrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeShutdownPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeLoadDriverPrivilege; - - Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED; + + Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; Privileges[i++].Luid = SeProfileSingleProcessPrivilege; - + Privileges[i].Attributes = 0; Privileges[i++].Luid = SeSystemtimePrivilege; ASSERT(i == 20); - + /* Setup the object attributes */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); ASSERT(SeSystemDefaultDacl != NULL); - + /* Create the token */ Status = SepCreateToken((PHANDLE)&Token, KernelMode, @@ -864,13 +867,13 @@ SepCreateSystemProcessToken(VOID) &SeSystemTokenSource, TRUE); ASSERT(Status == STATUS_SUCCESS); - + /* Return the token */ return Token; } /* PUBLIC FUNCTIONS ***********************************************************/ - + /* * @unimplemented */ @@ -915,14 +918,15 @@ SeQuerySessionIdToken(IN PACCESS_TOKEN Token, /* * @implemented */ -NTSTATUS NTAPI +NTSTATUS +NTAPI SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token, OUT PLUID LogonId) { PAGED_CODE(); - + *LogonId = ((PTOKEN)Token)->AuthenticationId; - + return STATUS_SUCCESS; } @@ -935,7 +939,7 @@ NTAPI SeTokenImpersonationLevel(IN PACCESS_TOKEN Token) { PAGED_CODE(); - + return ((PTOKEN)Token)->ImpersonationLevel; } @@ -947,7 +951,7 @@ TOKEN_TYPE NTAPI SeTokenType(IN PACCESS_TOKEN Token) { PAGED_CODE(); - + return ((PTOKEN)Token)->TokenType; } @@ -960,6 +964,7 @@ NTAPI SeTokenIsAdmin(IN PACCESS_TOKEN Token) { PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0; } @@ -971,6 +976,7 @@ NTAPI SeTokenIsRestricted(IN PACCESS_TOKEN Token) { PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0; } @@ -982,6 +988,7 @@ NTAPI SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token) { PAGED_CODE(); + return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0; } @@ -1006,11 +1013,11 @@ NtQueryInformationToken(IN HANDLE TokenHandle, ULONG RequiredLength; KPROCESSOR_MODE PreviousMode; NTSTATUS Status = STATUS_SUCCESS; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + /* Check buffers and class validity */ Status = DefaultQueryInfoBufferCheck(TokenInformationClass, SeTokenInformationClass, @@ -1020,13 +1027,12 @@ NtQueryInformationToken(IN HANDLE TokenHandle, ReturnLength, NULL, PreviousMode); - - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status); return Status; } - + Status = ObReferenceObjectByHandle(TokenHandle, (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY, SepTokenObjectType, @@ -1040,14 +1046,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle, case TokenUser: { PTOKEN_USER tu = (PTOKEN_USER)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenUser)\n"); RequiredLength = sizeof(TOKEN_USER) + RtlLengthSid(Token->UserAndGroups[0].Sid); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { Status = RtlCopySidAndAttributesArray(1, &Token->UserAndGroups[0], @@ -1061,8 +1067,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1072,27 +1078,27 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenGroups: { PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenGroups)\n"); RequiredLength = sizeof(tg->GroupCount) + RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)); PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES))); - + tg->GroupCount = Token->UserAndGroupCount - 1; Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1], @@ -1106,8 +1112,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1117,21 +1123,21 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenPrivileges: { PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenPrivileges)\n"); RequiredLength = sizeof(tp->PrivilegeCount) + (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { tp->PrivilegeCount = Token->PrivilegeCount; RtlCopyLuidAndAttributesArray(Token->PrivilegeCount, @@ -1142,8 +1148,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1153,22 +1159,22 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenOwner: { ULONG SidLen; PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenOwner)\n"); SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); RequiredLength = sizeof(TOKEN_OWNER) + SidLen; - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { to->Owner = (PSID)(to + 1); Status = RtlCopySid(SidLen, @@ -1179,8 +1185,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1190,22 +1196,22 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenPrimaryGroup: { ULONG SidLen; PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n"); SidLen = RtlLengthSid(Token->PrimaryGroup); RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen; - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { tpg->PrimaryGroup = (PSID)(tpg + 1); Status = RtlCopySid(SidLen, @@ -1216,8 +1222,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1227,27 +1233,27 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenDefaultDacl: { PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n"); RequiredLength = sizeof(TOKEN_DEFAULT_DACL); - - if(Token->DefaultDacl != NULL) + + if (Token->DefaultDacl != NULL) { RequiredLength += Token->DefaultDacl->AclSize; } - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { - if(Token->DefaultDacl != NULL) + if (Token->DefaultDacl != NULL) { tdd->DefaultDacl = (PACL)(tdd + 1); RtlCopyMemory(tdd->DefaultDacl, @@ -1263,8 +1269,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1274,20 +1280,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenSource: { PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenSource)\n"); RequiredLength = sizeof(TOKEN_SOURCE); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { *ts = Token->TokenSource; } @@ -1295,8 +1301,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1306,20 +1312,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenType: { PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenType)\n"); RequiredLength = sizeof(TOKEN_TYPE); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { *tt = Token->TokenType; } @@ -1327,8 +1333,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1338,14 +1344,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenImpersonationLevel: { PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n"); /* Fail if the token is not an impersonation token */ @@ -1356,10 +1362,10 @@ NtQueryInformationToken(IN HANDLE TokenHandle, } RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { *sil = Token->ImpersonationLevel; } @@ -1367,8 +1373,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1378,20 +1384,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenStatistics: { PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenStatistics)\n"); RequiredLength = sizeof(TOKEN_STATISTICS); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { ts->TokenId = Token->TokenId; ts->AuthenticationId = Token->AuthenticationId; @@ -1408,8 +1414,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1419,20 +1425,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenOrigin: { PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenOrigin)\n"); RequiredLength = sizeof(TOKEN_ORIGIN); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { RtlCopyLuid(&to->OriginatingLogonSession, &Token->AuthenticationId); @@ -1441,8 +1447,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1452,32 +1458,32 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenGroupsAndPrivileges: DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; - + case TokenRestrictedSids: { PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation; - + DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n"); RequiredLength = sizeof(tg->GroupCount) + RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids); - + _SEH2_TRY { - if(TokenInformationLength >= RequiredLength) + if (TokenInformationLength >= RequiredLength) { ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) - (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)); PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) + (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES))); - + tg->GroupCount = Token->RestrictedSidCount; Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount, Token->RestrictedSids, @@ -1491,8 +1497,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle, { Status = STATUS_BUFFER_TOO_SMALL; } - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = RequiredLength; } @@ -1502,32 +1508,32 @@ NtQueryInformationToken(IN HANDLE TokenHandle, Status = _SEH2_GetExceptionCode(); } _SEH2_END; - + break; } - + case TokenSandBoxInert: DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; - + case TokenSessionId: { ULONG SessionId = 0; - + DPRINT("NtQueryInformationToken(TokenSessionId)\n"); - + Status = SeQuerySessionIdToken(Token, &SessionId); - - if(NT_SUCCESS(Status)) + + if (NT_SUCCESS(Status)) { _SEH2_TRY { /* buffer size was already verified, no need to check here again */ *(PULONG)TokenInformation = SessionId; - - if(ReturnLength != NULL) + + if (ReturnLength != NULL) { *ReturnLength = sizeof(ULONG); } @@ -1538,20 +1544,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle, } _SEH2_END; } - + break; } - + default: DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass); Status = STATUS_INVALID_INFO_CLASS; break; } - + ObDereferenceObject(Token); } - - return(Status); + + return Status; } @@ -1571,30 +1577,29 @@ NtSetInformationToken(IN HANDLE TokenHandle, KPROCESSOR_MODE PreviousMode; ULONG NeededAccess = TOKEN_ADJUST_DEFAULT; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + Status = DefaultSetInfoBufferCheck(TokenInformationClass, SeTokenInformationClass, sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]), TokenInformation, TokenInformationLength, PreviousMode); - - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { /* Invalid buffers */ DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status); return Status; } - - if(TokenInformationClass == TokenSessionId) + + if (TokenInformationClass == TokenSessionId) { NeededAccess |= TOKEN_ADJUST_SESSIONID; } - + Status = ObReferenceObjectByHandle(TokenHandle, NeededAccess, SepTokenObjectType, @@ -1607,11 +1612,11 @@ NtSetInformationToken(IN HANDLE TokenHandle, { case TokenOwner: { - if(TokenInformationLength >= sizeof(TOKEN_OWNER)) + if (TokenInformationLength >= sizeof(TOKEN_OWNER)) { PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation; PSID InputSid = NULL, CapturedSid; - + _SEH2_TRY { InputSid = to->Owner; @@ -1621,13 +1626,13 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + Status = SepCaptureSid(InputSid, PreviousMode, PagedPool, FALSE, &CapturedSid); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { RtlCopySid(RtlLengthSid(CapturedSid), Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, @@ -1643,14 +1648,14 @@ NtSetInformationToken(IN HANDLE TokenHandle, } break; } - + case TokenPrimaryGroup: { - if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP)) + if (TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP)) { PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation; PSID InputSid = NULL, CapturedSid; - + _SEH2_TRY { InputSid = tpg->PrimaryGroup; @@ -1660,13 +1665,13 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - + Status = SepCaptureSid(InputSid, PreviousMode, PagedPool, FALSE, &CapturedSid); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { RtlCopySid(RtlLengthSid(CapturedSid), Token->PrimaryGroup, @@ -1682,14 +1687,14 @@ NtSetInformationToken(IN HANDLE TokenHandle, } break; } - + case TokenDefaultDacl: { - if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL)) + if (TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL)) { PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation; PACL InputAcl = NULL; - + _SEH2_TRY { InputAcl = tdd->DefaultDacl; @@ -1700,32 +1705,32 @@ NtSetInformationToken(IN HANDLE TokenHandle, } _SEH2_END; - if(InputAcl != NULL) + if (InputAcl != NULL) { PACL CapturedAcl; - /* capture and copy the dacl */ + /* Capture and copy the dacl */ Status = SepCaptureAcl(InputAcl, PreviousMode, PagedPool, TRUE, &CapturedAcl); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { - /* free the previous dacl if present */ + /* Free the previous dacl if present */ if(Token->DefaultDacl != NULL) { ExFreePool(Token->DefaultDacl); } - /* set the new dacl */ + /* Set the new dacl */ Token->DefaultDacl = CapturedAcl; } } else { - /* clear and free the default dacl if present */ - if(Token->DefaultDacl != NULL) + /* Clear and free the default dacl if present */ + if (Token->DefaultDacl != NULL) { ExFreePool(Token->DefaultDacl); Token->DefaultDacl = NULL; @@ -1738,14 +1743,14 @@ NtSetInformationToken(IN HANDLE TokenHandle, } break; } - + case TokenSessionId: { ULONG SessionId = 0; - + _SEH2_TRY { - /* buffer size was already verified, no need to check here again */ + /* Buffer size was already verified, no need to check here again */ SessionId = *(PULONG)TokenInformation; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -1753,9 +1758,9 @@ NtSetInformationToken(IN HANDLE TokenHandle, _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - - if(!SeSinglePrivilegeCheck(SeTcbPrivilege, - PreviousMode)) + + if (!SeSinglePrivilegeCheck(SeTcbPrivilege, + PreviousMode)) { Status = STATUS_PRIVILEGE_NOT_HELD; break; @@ -1764,18 +1769,18 @@ NtSetInformationToken(IN HANDLE TokenHandle, Token->SessionId = SessionId; break; } - + default: { Status = STATUS_NOT_IMPLEMENTED; break; } } - + ObDereferenceObject(Token); } - - return(Status); + + return Status; } @@ -1801,12 +1806,13 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, PTOKEN NewToken; PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService; BOOLEAN QoSPresent; + OBJECT_HANDLE_INFORMATION HandleInformation; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = KeGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -1820,66 +1826,103 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, } _SEH2_END; } - + Status = SepCaptureSecurityQualityOfService(ObjectAttributes, PreviousMode, PagedPool, FALSE, &CapturedSecurityQualityOfService, &QoSPresent); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status); return Status; } - + Status = ObReferenceObjectByHandle(ExistingTokenHandle, TOKEN_DUPLICATE, SepTokenObjectType, PreviousMode, (PVOID*)&Token, - NULL); - if (NT_SUCCESS(Status)) + &HandleInformation); + if (!NT_SUCCESS(Status)) { - Status = SepDuplicateToken(Token, - ObjectAttributes, - EffectiveOnly, - TokenType, - (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), - PreviousMode, - &NewToken); - - ObDereferenceObject(Token); - - if (NT_SUCCESS(Status)) + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return Status; + } + + /* + * Fail, if the original token is an impersonation token and the caller + * tries to raise the impersonation level of the new token above the + * impersonation level of the original token. + */ + if (Token->TokenType == TokenImpersonation) + { + if (QoSPresent && + CapturedSecurityQualityOfService->ImpersonationLevel >Token->ImpersonationLevel) { - Status = ObInsertObject((PVOID)NewToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - - if (NT_SUCCESS(Status)) - { - _SEH2_TRY - { - *NewTokenHandle = hToken; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } + ObDereferenceObject(Token); + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return STATUS_BAD_IMPERSONATION_LEVEL; } } - - /* free the captured structure */ + + /* + * Fail, if a primary token is to be created from an impersonation token + * and and the impersonation level of the impersonation token is below SecurityImpersonation. + */ + if (Token->TokenType == TokenImpersonation && + TokenType == TokenPrimary && + Token->ImpersonationLevel < SecurityImpersonation) + { + ObDereferenceObject(Token); + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + + Status = SepDuplicateToken(Token, + ObjectAttributes, + EffectiveOnly, + TokenType, + (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), + PreviousMode, + &NewToken); + + ObDereferenceObject(Token); + + if (NT_SUCCESS(Status)) + { + Status = ObInsertObject((PVOID)NewToken, + NULL, + (DesiredAccess ? DesiredAccess : HandleInformation.GrantedAccess), + 0, + NULL, + &hToken); + if (NT_SUCCESS(Status)) + { + _SEH2_TRY + { + *NewTokenHandle = hToken; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + + /* Free the captured structure */ SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, PreviousMode, FALSE); - + return Status; } @@ -1899,12 +1942,12 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle, * @implemented */ NTSTATUS NTAPI -NtAdjustPrivilegesToken (IN HANDLE TokenHandle, - IN BOOLEAN DisableAllPrivileges, - IN PTOKEN_PRIVILEGES NewState, - IN ULONG BufferLength, - OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL, - OUT PULONG ReturnLength OPTIONAL) +NtAdjustPrivilegesToken(IN HANDLE TokenHandle, + IN BOOLEAN DisableAllPrivileges, + IN PTOKEN_PRIVILEGES NewState, + IN ULONG BufferLength, + OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL, + OUT PULONG ReturnLength OPTIONAL) { // PLUID_AND_ATTRIBUTES Privileges; KPROCESSOR_MODE PreviousMode; @@ -1921,11 +1964,11 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, ULONG c; #endif NTSTATUS Status; - + PAGED_CODE(); - + DPRINT ("NtAdjustPrivilegesToken() called\n"); - + // PrivilegeCount = NewState->PrivilegeCount; PreviousMode = KeGetPreviousMode (); // SeCaptureLuidAndAttributesArray(NewState->Privileges, @@ -1937,7 +1980,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, // 1, // &Privileges, // &Length); - + Status = ObReferenceObjectByHandle (TokenHandle, TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0), SepTokenObjectType, @@ -1952,8 +1995,8 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, // 0); return Status; } - - + + #if 0 SepAdjustPrivileges(Token, 0, @@ -1965,13 +2008,13 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, &b, &c); #endif - + PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) / sizeof(LUID_AND_ATTRIBUTES); - + if (PreviousState != NULL) PreviousState->PrivilegeCount = 0; - + k = 0; if (DisableAllPrivileges == TRUE) { @@ -1980,7 +2023,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, if (Token->Privileges[i].Attributes != 0) { DPRINT ("Attributes differ\n"); - + /* Save current privilege */ if (PreviousState != NULL) { @@ -1992,18 +2035,21 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, } else { - /* FIXME: Should revert all the changes, calculate how + /* + * FIXME: Should revert all the changes, calculate how * much space would be needed, set ResultLength * accordingly and fail. */ } + k++; } - + /* Update current privlege */ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; } } + Status = STATUS_SUCCESS; } else @@ -2017,7 +2063,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart) { DPRINT ("Found privilege\n"); - + if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) != (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED)) { @@ -2025,7 +2071,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, DPRINT ("Current attributes %lx desired attributes %lx\n", Token->Privileges[i].Attributes, NewState->Privileges[j].Attributes); - + /* Save current privilege */ if (PreviousState != NULL) { @@ -2037,14 +2083,16 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, } else { - /* FIXME: Should revert all the changes, calculate how + /* + * FIXME: Should revert all the changes, calculate how * much space would be needed, set ResultLength * accordingly and fail. */ } + k++; } - + /* Update current privlege */ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED; Token->Privileges[i].Attributes |= @@ -2052,27 +2100,29 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle, DPRINT ("New attributes %lx\n", Token->Privileges[i].Attributes); } + Count++; } } } + Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS; } - + if (ReturnLength != NULL) { *ReturnLength = sizeof(TOKEN_PRIVILEGES) + (sizeof(LUID_AND_ATTRIBUTES) * (k - 1)); } - + ObDereferenceObject (Token); - + // SeReleaseLuidAndAttributesArray(Privileges, // PreviousMode, // 0); - + DPRINT ("NtAdjustPrivilegesToken() done\n"); - + return Status; } @@ -2097,12 +2147,12 @@ NtCreateToken(OUT PHANDLE TokenHandle, ULONG nTokenPrivileges = 0; LARGE_INTEGER LocalExpirationTime = {{0, 0}}; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) + + if (PreviousMode != KernelMode) { _SEH2_TRY { @@ -2146,7 +2196,7 @@ NtCreateToken(OUT PHANDLE TokenHandle, nTokenPrivileges = TokenPrivileges->PrivilegeCount; LocalExpirationTime = *ExpirationTime; } - + Status = SepCreateToken(&hToken, PreviousMode, DesiredAccess, @@ -2178,7 +2228,7 @@ NtCreateToken(OUT PHANDLE TokenHandle, } _SEH2_END; } - + return Status; } @@ -2204,11 +2254,11 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, PACL Dacl = NULL; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -2222,12 +2272,12 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, } _SEH2_END; } - + /* * At first open the thread token for information access and verify * that the token associated with thread is valid. */ - + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, PsThreadType, PreviousMode, (PVOID*)&Thread, NULL); @@ -2235,7 +2285,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, { return Status; } - + Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly, &ImpersonationLevel); if (Token == NULL) @@ -2243,23 +2293,23 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, ObDereferenceObject(Thread); return STATUS_NO_TOKEN; } - + if (ImpersonationLevel == SecurityAnonymous) { PsDereferenceImpersonationToken(Token); ObDereferenceObject(Thread); return STATUS_CANT_OPEN_ANONYMOUS; } - + /* * Revert to self if OpenAsSelf is specified. */ - + if (OpenAsSelf) { PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState); } - + if (CopyOnOpen) { Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, @@ -2268,11 +2318,11 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, if (NT_SUCCESS(Status)) { PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess); - + Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl); ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken); - + if (NT_SUCCESS(Status)) { if (Dacl) @@ -2282,10 +2332,10 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, FALSE); } - + InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes, NULL, Dacl ? &SecurityDescriptor : NULL); - + Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly, TokenImpersonation, ImpersonationLevel, @@ -2305,26 +2355,26 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, NULL, DesiredAccess, SepTokenObjectType, PreviousMode, &hToken); } - + if (Dacl) ExFreePool(Dacl); - + if (OpenAsSelf) { PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState); } - + ObDereferenceObject(Token); - + if (NT_SUCCESS(Status) && CopyOnOpen) { PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel); } - + if (NewToken) ObDereferenceObject(NewToken); if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { _SEH2_TRY { @@ -2336,7 +2386,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle, } _SEH2_END; } - + return Status; } @@ -2368,11 +2418,11 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, PTOKEN FirstToken, SecondToken; BOOLEAN IsEqual; NTSTATUS Status; - + PAGED_CODE(); - + PreviousMode = ExGetPreviousMode(); - + if (PreviousMode != KernelMode) { _SEH2_TRY @@ -2386,7 +2436,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } _SEH2_END; } - + Status = ObReferenceObjectByHandle(FirstTokenHandle, TOKEN_QUERY, SepTokenObjectType, @@ -2395,7 +2445,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, NULL); if (!NT_SUCCESS(Status)) return Status; - + Status = ObReferenceObjectByHandle(SecondTokenHandle, TOKEN_QUERY, SepTokenObjectType, @@ -2407,7 +2457,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, ObDereferenceObject(FirstToken); return Status; } - + if (FirstToken != SecondToken) { Status = SepCompareTokens(FirstToken, @@ -2416,10 +2466,10 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } else IsEqual = TRUE; - + ObDereferenceObject(FirstToken); ObDereferenceObject(SecondToken); - + if (NT_SUCCESS(Status)) { _SEH2_TRY @@ -2432,7 +2482,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle, } _SEH2_END; } - + return Status; } diff --git a/subsystems/win32/csrss/csrsrv/api/handle.c b/subsystems/win32/csrss/csrsrv/api/handle.c deleted file mode 100644 index eb6c12c0531..00000000000 --- a/subsystems/win32/csrss/csrsrv/api/handle.c +++ /dev/null @@ -1,253 +0,0 @@ -/* $Id$ - * - * reactos/subsys/csrss/api/handle.c - * - * CSRSS handle functions - * - * ReactOS Operating System - */ - -/* INCLUDES ******************************************************************/ - -#include - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -static unsigned ObjectDefinitionsCount = 0; -static PCSRSS_OBJECT_DEFINITION ObjectDefinitions = NULL; - -static -BOOL -CsrIsConsoleHandle(HANDLE Handle) -{ - return ((ULONG_PTR)Handle & 0x10000003) == 0x3; -} - - -NTSTATUS -FASTCALL -CsrRegisterObjectDefinitions( - PCSRSS_OBJECT_DEFINITION NewDefinitions) -{ - unsigned NewCount; - PCSRSS_OBJECT_DEFINITION Scan; - PCSRSS_OBJECT_DEFINITION New; - - NewCount = 0; - for (Scan = NewDefinitions; 0 != Scan->Type; Scan++) - { - NewCount++; - } - - New = RtlAllocateHeap(CsrssApiHeap, - 0, - (ObjectDefinitionsCount + NewCount) - * sizeof(CSRSS_OBJECT_DEFINITION)); - if (NULL == New) - { - DPRINT1("Unable to allocate memory\n"); - return STATUS_NO_MEMORY; - } - - if (0 != ObjectDefinitionsCount) - { - RtlCopyMemory(New, - ObjectDefinitions, - ObjectDefinitionsCount * sizeof(CSRSS_OBJECT_DEFINITION)); - RtlFreeHeap(CsrssApiHeap, 0, ObjectDefinitions); - } - - RtlCopyMemory(New + ObjectDefinitionsCount, - NewDefinitions, - NewCount * sizeof(CSRSS_OBJECT_DEFINITION)); - ObjectDefinitions = New; - ObjectDefinitionsCount += NewCount; - - return STATUS_SUCCESS; -} - -NTSTATUS -WINAPI -CsrGetObject( - PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access ) -{ - ULONG_PTR h = (ULONG_PTR)Handle >> 2; - - DPRINT("CsrGetObject, Object: %x, %x, %x\n", - Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize - || (*Object = ProcessData->HandleTable[h].Object) == NULL - || ~ProcessData->HandleTable[h].Access & Access) - { - DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; - } - _InterlockedIncrement(&(*Object)->ReferenceCount); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - // DbgPrint( "CsrGetObject returning\n" ); - return STATUS_SUCCESS; -} - - -NTSTATUS -WINAPI -CsrReleaseObjectByPointer( - Object_t *Object) -{ - unsigned DefIndex; - - /* dec ref count */ - if (_InterlockedDecrement(&Object->ReferenceCount) == 0) - { - for (DefIndex = 0; DefIndex < ObjectDefinitionsCount; DefIndex++) - { - if (Object->Type == ObjectDefinitions[DefIndex].Type) - { - (ObjectDefinitions[DefIndex].CsrCleanupObjectProc)(Object); - return STATUS_SUCCESS; - } - } - - DPRINT1("CSR: Error: releasing unknown object type 0x%x", Object->Type); - } - - return STATUS_SUCCESS; -} - - -NTSTATUS -WINAPI -CsrReleaseObject( - PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle) -{ - ULONG_PTR h = (ULONG_PTR)Handle >> 2; - Object_t *Object; - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (h >= ProcessData->HandleTableSize - || (Object = ProcessData->HandleTable[h].Object) == NULL) - { - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; - } - ProcessData->HandleTable[h].Object = NULL; - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - - return CsrReleaseObjectByPointer(Object); -} - -NTSTATUS -WINAPI -CsrInsertObject( - PCSRSS_PROCESS_DATA ProcessData, - PHANDLE Handle, - Object_t *Object, - DWORD Access, - BOOL Inheritable) -{ - ULONG i; - PVOID* Block; - - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - - for (i = 0; i < ProcessData->HandleTableSize; i++) - { - if (ProcessData->HandleTable[i].Object == NULL) - { - break; - } - } - if (i >= ProcessData->HandleTableSize) - { - Block = RtlAllocateHeap(CsrssApiHeap, - HEAP_ZERO_MEMORY, - (ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE)); - if (Block == NULL) - { - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return(STATUS_UNSUCCESSFUL); - } - RtlCopyMemory(Block, - ProcessData->HandleTable, - ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE)); - Block = _InterlockedExchangePointer((void* volatile)&ProcessData->HandleTable, Block); - RtlFreeHeap( CsrssApiHeap, 0, Block ); - ProcessData->HandleTableSize += 64; - } - ProcessData->HandleTable[i].Object = Object; - ProcessData->HandleTable[i].Access = Access; - ProcessData->HandleTable[i].Inheritable = Inheritable; - *Handle = UlongToHandle((i << 2) | 0x3); - _InterlockedIncrement( &Object->ReferenceCount ); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return(STATUS_SUCCESS); -} - -NTSTATUS -WINAPI -CsrDuplicateHandleTable( - PCSRSS_PROCESS_DATA SourceProcessData, - PCSRSS_PROCESS_DATA TargetProcessData) -{ - ULONG i; - - if (TargetProcessData->HandleTableSize) - { - return STATUS_INVALID_PARAMETER; - } - - RtlEnterCriticalSection(&SourceProcessData->HandleTableLock); - - /* we are called from CreateProcessData, it isn't necessary to lock the target process data */ - - TargetProcessData->HandleTable = RtlAllocateHeap(CsrssApiHeap, - HEAP_ZERO_MEMORY, - SourceProcessData->HandleTableSize - * sizeof(CSRSS_HANDLE)); - if (TargetProcessData->HandleTable == NULL) - { - RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); - return(STATUS_UNSUCCESSFUL); - } - TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize; - for (i = 0; i < SourceProcessData->HandleTableSize; i++) - { - if (SourceProcessData->HandleTable[i].Object != NULL && - SourceProcessData->HandleTable[i].Inheritable) - { - TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i]; - _InterlockedIncrement( &SourceProcessData->HandleTable[i].Object->ReferenceCount ); - } - } - RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); - return(STATUS_SUCCESS); -} - -NTSTATUS -WINAPI -CsrVerifyObject( - PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle) -{ - ULONG_PTR h = (ULONG_PTR)Handle >> 2; - - if (h >= ProcessData->HandleTableSize || - ProcessData->HandleTable[h].Object == NULL) - { - return STATUS_INVALID_HANDLE; - } - - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/subsystems/win32/csrss/csrsrv/api/process.c b/subsystems/win32/csrss/csrsrv/api/process.c index 5fcac045c70..8b7a4832f8d 100644 --- a/subsystems/win32/csrss/csrsrv/api/process.c +++ b/subsystems/win32/csrss/csrsrv/api/process.c @@ -18,6 +18,9 @@ #define CsrAcquireProcessLock() LOCK #define CsrReleaseProcessLock() UNLOCK +extern NTSTATUS CallProcessInherit(PCSRSS_PROCESS_DATA, PCSRSS_PROCESS_DATA); +extern NTSTATUS CallProcessDeleted(PCSRSS_PROCESS_DATA); + /* GLOBALS *******************************************************************/ static ULONG NrProcess; @@ -140,7 +143,6 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId) NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) { ULONG hash; - UINT c; PCSRSS_PROCESS_DATA pProcessData, *pPrevLink; HANDLE Process; @@ -158,23 +160,7 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) { DPRINT("CsrFreeProcessData pid: %d\n", Pid); Process = pProcessData->Process; - if (pProcessData->HandleTable) - { - for (c = 0; c < pProcessData->HandleTableSize; c++) - { - if (pProcessData->HandleTable[c].Object) - { - CsrReleaseObjectByPointer(pProcessData->HandleTable[c].Object); - } - } - RtlFreeHeap(CsrssApiHeap, 0, pProcessData->HandleTable); - } - RtlDeleteCriticalSection(&pProcessData->HandleTableLock); - if (pProcessData->Console) - { - RemoveEntryList(&pProcessData->ProcessEntry); - CsrReleaseObjectByPointer((Object_t *) pProcessData->Console); - } + CallProcessDeleted(pProcessData); if (pProcessData->CsrSectionViewBase) { NtUnmapViewOfSection(NtCurrentProcess(), pProcessData->CsrSectionViewBase); @@ -222,7 +208,7 @@ CSR_API(CsrCreateProcess) NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles; if (Request->Data.CreateProcessRequest.bInheritHandles) { - Status = CsrDuplicateHandleTable(ProcessData, NewProcessData); + Status = CallProcessInherit(ProcessData, NewProcessData); } } @@ -360,134 +346,4 @@ CSR_API(CsrSetShutdownParameters) return(STATUS_SUCCESS); } -CSR_API(CsrGetInputHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (ProcessData->Console) - { - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.GetInputHandleRequest.InputHandle, - (Object_t *)ProcessData->Console, - Request->Data.GetInputHandleRequest.Access, - Request->Data.GetInputHandleRequest.Inheritable); - } - else - { - Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; - } - - return Request->Status; -} - -CSR_API(CsrGetOutputHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (ProcessData->Console) - { - RtlEnterCriticalSection(&ProcessDataLock); - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.GetOutputHandleRequest.OutputHandle, - &ProcessData->Console->ActiveBuffer->Header, - Request->Data.GetOutputHandleRequest.Access, - Request->Data.GetOutputHandleRequest.Inheritable); - RtlLeaveCriticalSection(&ProcessDataLock); - } - else - { - Request->Data.GetOutputHandleRequest.OutputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; - } - - return Request->Status; -} - -CSR_API(CsrCloseHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - return CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); -} - -CSR_API(CsrVerifyHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Request->Status = CsrVerifyObject(ProcessData, Request->Data.VerifyHandleRequest.Handle); - if (!NT_SUCCESS(Request->Status)) - { - DPRINT("CsrVerifyObject failed, status=%x\n", Request->Status); - } - - return Request->Status; -} - -CSR_API(CsrDuplicateHandle) -{ - ULONG_PTR Index; - PCSRSS_HANDLE Entry; - DWORD DesiredAccess; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Index = (ULONG_PTR)Request->Data.DuplicateHandleRequest.Handle >> 2; - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - if (Index >= ProcessData->HandleTableSize - || (Entry = &ProcessData->HandleTable[Index])->Object == NULL) - { - DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_HANDLE; - } - - if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS) - { - DesiredAccess = Entry->Access; - } - else - { - DesiredAccess = Request->Data.DuplicateHandleRequest.Access; - /* Make sure the source handle has all the desired flags */ - if (~Entry->Access & DesiredAccess) - { - DPRINT1("Handle %p only has access %X; requested %X\n", - Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess); - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return STATUS_INVALID_PARAMETER; - } - } - - Request->Status = CsrInsertObject(ProcessData, - &Request->Data.DuplicateHandleRequest.Handle, - Entry->Object, - DesiredAccess, - Request->Data.DuplicateHandleRequest.Inheritable); - if (NT_SUCCESS(Request->Status) - && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) - { - /* Close the original handle. This cannot drop the count to 0, since a new handle now exists */ - _InterlockedDecrement(&Entry->Object->ReferenceCount); - Entry->Object = NULL; - } - - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Request->Status; -} - -CSR_API(CsrGetInputWaitHandle) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Request->Data.GetConsoleInputWaitHandle.InputWaitHandle = ProcessData->ConsoleEvent; - return STATUS_SUCCESS; -} - /* EOF */ diff --git a/subsystems/win32/csrss/csrsrv/csrsrv.rbuild b/subsystems/win32/csrss/csrsrv/csrsrv.rbuild index 3f002106bfe..c7b9b53acff 100644 --- a/subsystems/win32/csrss/csrsrv/csrsrv.rbuild +++ b/subsystems/win32/csrss/csrsrv/csrsrv.rbuild @@ -10,7 +10,6 @@ pseh smdll - handle.c process.c user.c wapi.c diff --git a/subsystems/win32/csrss/csrsrv/init.c b/subsystems/win32/csrss/csrsrv/init.c index 51adb2cacca..c66411cf18a 100644 --- a/subsystems/win32/csrss/csrsrv/init.c +++ b/subsystems/win32/csrss/csrsrv/init.c @@ -18,10 +18,8 @@ HANDLE CsrHeap = (HANDLE) 0; HANDLE CsrObjectDirectory = (HANDLE) 0; UNICODE_STRING CsrDirectoryName; extern HANDLE CsrssApiHeap; -static unsigned InitCompleteProcCount; -static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL; -static unsigned HardErrorProcCount; -static CSRPLUGIN_HARDERROR_PROC *HardErrorProcs = NULL; +static unsigned ServerProcCount; +static CSRPLUGIN_SERVER_PROCS *ServerProcs = NULL; HANDLE hSbApiPort = (HANDLE) 0; HANDLE hBootstrapOk = (HANDLE) 0; HANDLE hSmApiPort = (HANDLE) 0; @@ -124,60 +122,32 @@ InitializeVideoAddressSpace(VOID) static NTSTATUS FASTCALL -CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) +CsrpAddServerProcs(CSRPLUGIN_SERVER_PROCS *Procs) { - CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs; + CSRPLUGIN_SERVER_PROCS *NewProcs; DPRINT("CSR: %s called\n", __FUNCTION__); NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, - (InitCompleteProcCount + 1) - * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC)); + (ServerProcCount + 1) + * sizeof(CSRPLUGIN_SERVER_PROCS)); if (NULL == NewProcs) { return STATUS_NO_MEMORY; } - if (0 != InitCompleteProcCount) + if (0 != ServerProcCount) { - RtlCopyMemory(NewProcs, InitCompleteProcs, - InitCompleteProcCount * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC)); - RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs); + RtlCopyMemory(NewProcs, ServerProcs, + ServerProcCount * sizeof(CSRPLUGIN_SERVER_PROCS)); + RtlFreeHeap(CsrssApiHeap, 0, ServerProcs); } - NewProcs[InitCompleteProcCount] = Proc; - InitCompleteProcs = NewProcs; - InitCompleteProcCount++; + NewProcs[ServerProcCount] = *Procs; + ServerProcs = NewProcs; + ServerProcCount++; return STATUS_SUCCESS; } -static NTSTATUS FASTCALL -CsrpAddHardErrorProc(CSRPLUGIN_HARDERROR_PROC Proc) -{ - CSRPLUGIN_HARDERROR_PROC *NewProcs; - - DPRINT("CSR: %s called\n", __FUNCTION__); - - NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, - (HardErrorProcCount + 1) - * sizeof(CSRPLUGIN_HARDERROR_PROC)); - if (NULL == NewProcs) - { - return STATUS_NO_MEMORY; - } - if (0 != HardErrorProcCount) - { - RtlCopyMemory(NewProcs, HardErrorProcs, - HardErrorProcCount * sizeof(CSRPLUGIN_HARDERROR_PROC)); - RtlFreeHeap(CsrssApiHeap, 0, HardErrorProcs); - } - - NewProcs[HardErrorProcCount] = Proc; - HardErrorProcs = NewProcs; - HardErrorProcCount++; - - return STATUS_SUCCESS; -} - /********************************************************************** * CallInitComplete/0 */ @@ -190,13 +160,9 @@ CallInitComplete(void) DPRINT("CSR: %s called\n", __FUNCTION__); Ok = TRUE; - if (0 != InitCompleteProcCount) + for (i = 0; i < ServerProcCount && Ok; i++) { - for (i = 0; i < InitCompleteProcCount && Ok; i++) - { - Ok = (*(InitCompleteProcs[i]))(); - } - RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs); + Ok = (*ServerProcs[i].InitCompleteProc)(); } return Ok; @@ -212,17 +178,44 @@ CallHardError(IN PCSRSS_PROCESS_DATA ProcessData, DPRINT("CSR: %s called\n", __FUNCTION__); Ok = TRUE; - if (0 != HardErrorProcCount) + for (i = 0; i < ServerProcCount && Ok; i++) { - for (i = 0; i < HardErrorProcCount && Ok; i++) - { - Ok = (*(HardErrorProcs[i]))(ProcessData, HardErrorMessage); - } + Ok = (*ServerProcs[i].HardErrorProc)(ProcessData, HardErrorMessage); } return Ok; } +NTSTATUS +CallProcessInherit(IN PCSRSS_PROCESS_DATA SourceProcessData, + IN PCSRSS_PROCESS_DATA TargetProcessData) +{ + NTSTATUS Status = STATUS_SUCCESS; + unsigned i; + + DPRINT("CSR: %s called\n", __FUNCTION__); + + for (i = 0; i < ServerProcCount && NT_SUCCESS(Status); i++) + Status = (*ServerProcs[i].ProcessInheritProc)(SourceProcessData, TargetProcessData); + + return Status; +} + +NTSTATUS +CallProcessDeleted(IN PCSRSS_PROCESS_DATA ProcessData) +{ + NTSTATUS Status = STATUS_SUCCESS; + unsigned i; + + DPRINT("CSR: %s called\n", __FUNCTION__); + + for (i = 0; i < ServerProcCount && NT_SUCCESS(Status); i++) + Status = (*ServerProcs[i].ProcessDeletedProc)(ProcessData); + + return Status; +} + + ULONG InitializeVideoAddressSpace(VOID); @@ -313,9 +306,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) CSRPLUGIN_INITIALIZE_PROC InitProc; CSRSS_EXPORTED_FUNCS Exports; PCSRSS_API_DEFINITION ApiDefinitions; - PCSRSS_OBJECT_DEFINITION ObjectDefinitions; - CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc; - CSRPLUGIN_HARDERROR_PROC HardErrorProc; + CSRPLUGIN_SERVER_PROCS ServerProcs; DPRINT("CSR: %s called\n", __FUNCTION__); @@ -331,13 +322,8 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) { return Status; } - Exports.CsrInsertObjectProc = CsrInsertObject; - Exports.CsrGetObjectProc = CsrGetObject; - Exports.CsrReleaseObjectByPointerProc = CsrReleaseObjectByPointer; - Exports.CsrReleaseObjectProc = CsrReleaseObject; Exports.CsrEnumProcessesProc = CsrEnumProcesses; - if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc, - &HardErrorProc, &Exports, CsrssApiHeap)) + if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrssApiHeap)) { return STATUS_UNSUCCESSFUL; } @@ -347,17 +333,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp) { return Status; } - Status = CsrRegisterObjectDefinitions(ObjectDefinitions); - if (! NT_SUCCESS(Status)) - { - return Status; - } - if (NULL != InitCompleteProc) - { - Status = CsrpAddInitCompleteProc(InitCompleteProc); - } - if (HardErrorProc) Status = CsrpAddHardErrorProc(HardErrorProc); - + Status = CsrpAddServerProcs(&ServerProcs); return Status; } @@ -370,12 +346,6 @@ CSRSS_API_DEFINITION NativeDefinitions[] = CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess), CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters), CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters), - CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle), - CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle), - CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), - CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), - CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), - CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle), { 0, 0, NULL } }; diff --git a/subsystems/win32/csrss/csrsrv/srv.h b/subsystems/win32/csrss/csrsrv/srv.h index cc11b70603c..b784e6ed575 100644 --- a/subsystems/win32/csrss/csrsrv/srv.h +++ b/subsystems/win32/csrss/csrsrv/srv.h @@ -17,5 +17,4 @@ /* Internal CSRSS Headers */ #include -#include #include diff --git a/subsystems/win32/csrss/include/api.h b/subsystems/win32/csrss/include/api.h index 7fbf6db9e58..7e956b66698 100644 --- a/subsystems/win32/csrss/include/api.h +++ b/subsystems/win32/csrss/include/api.h @@ -44,39 +44,14 @@ typedef enum _CSR_PROCESS_FLAGS CsrProcessIsConsoleApp = 0x800 } CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS; -typedef struct Object_tt -{ - LONG Type; - LONG ReferenceCount; - CRITICAL_SECTION Lock; -} Object_t; - -typedef struct ConsoleInput_t -{ - LIST_ENTRY ListEntry; - INPUT_RECORD InputEvent; - BOOLEAN Echoed; // already been echoed or not - BOOLEAN Fake; // synthesized, not a real event - BOOLEAN NotChar; // message should not be used to return a character -} ConsoleInput; - -typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; - -typedef struct _CSRSS_HANDLE -{ - Object_t *Object; - DWORD Access; - BOOL Inheritable; -} CSRSS_HANDLE, *PCSRSS_HANDLE; - typedef struct _CSRSS_PROCESS_DATA { - PCSRSS_CONSOLE Console; - PCSRSS_CONSOLE ParentConsole; + struct tagCSRSS_CONSOLE *Console; + struct tagCSRSS_CONSOLE *ParentConsole; BOOL bInheritHandles; RTL_CRITICAL_SECTION HandleTableLock; ULONG HandleTableSize; - PCSRSS_HANDLE HandleTable; + struct _CSRSS_HANDLE *HandleTable; HANDLE ProcessId; DWORD ProcessGroup; HANDLE Process; @@ -109,14 +84,6 @@ typedef struct _CSR_THREAD ULONG ImpersonationCount; } CSR_THREAD, *PCSR_THREAD; -typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); - -typedef struct tagCSRSS_OBJECT_DEFINITION -{ - LONG Type; - CSR_CLEANUP_OBJECT_PROC CsrCleanupObjectProc; -} CSRSS_OBJECT_DEFINITION, *PCSRSS_OBJECT_DEFINITION; - typedef NTSTATUS (WINAPI *CSRSS_API_PROC)(PCSRSS_PROCESS_DATA ProcessData, PCSR_API_MESSAGE Request); @@ -143,33 +110,25 @@ PCSR_API_MESSAGE Request) /* init.c */ extern HANDLE hBootstrapOk; +NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); /* api/process.c */ CSR_API(CsrConnectProcess); CSR_API(CsrCreateProcess); CSR_API(CsrTerminateProcess); CSR_API(CsrSrvCreateThread); - -/* print.c */ -VOID WINAPI DisplayString(LPCWSTR lpwString); -VOID WINAPI PrintString (char* fmt, ...); +CSR_API(CsrGetShutdownParameters); +CSR_API(CsrSetShutdownParameters); /* api/wapi.c */ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions); VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData, PCSR_API_MESSAGE Request); -DWORD WINAPI ServerApiPortThread (PVOID PortHandle); DWORD WINAPI ServerSbApiPortThread (PVOID PortHandle); -DWORD WINAPI Console_Api( PVOID unused ); -VOID -NTAPI -ClientConnectionThread(HANDLE ServerPort); +VOID NTAPI ClientConnectionThread(HANDLE ServerPort); extern HANDLE CsrssApiHeap; -/* api/conio.c */ -VOID WINAPI CsrInitConsoleSupport(VOID); - /* api/process.c */ typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSRSS_PROCESS_DATA ProcessData, PVOID Context); @@ -185,33 +144,10 @@ NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSRSS_PROCESS_DATA * NTSTATUS NTAPI CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId); NTSTATUS NTAPI CsrUnlockProcess(IN PCSRSS_PROCESS_DATA CsrProcess); -/* api/handle.c */ -NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions); -NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable ); -NTSTATUS WINAPI CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData); -NTSTATUS WINAPI CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, DWORD Access ); -NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); -NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object); -NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); -NTSTATUS WINAPI CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); - //hack VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); -CSR_API(CsrGetInputHandle); -CSR_API(CsrGetOutputHandle); -CSR_API(CsrCloseHandle); -CSR_API(CsrVerifyHandle); -CSR_API(CsrDuplicateHandle); -CSR_API(CsrGetInputWaitHandle); - /* api/user.c */ CSR_API(CsrRegisterServicesProcess); -CSR_API(CsrExitReactos); -CSR_API(CsrGetShutdownParameters); -CSR_API(CsrSetShutdownParameters); - -CSR_API(CsrSetLogonNotifyWindow); -CSR_API(CsrRegisterLogonProcess); /* EOF */ diff --git a/subsystems/win32/csrss/include/csrplugin.h b/subsystems/win32/csrss/include/csrplugin.h index 357b65bcd25..20830bc76eb 100644 --- a/subsystems/win32/csrss/include/csrplugin.h +++ b/subsystems/win32/csrss/include/csrplugin.h @@ -21,27 +21,11 @@ #include #include "api.h" -typedef NTSTATUS (WINAPI *CSRSS_INSERT_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, - PHANDLE Handle, - Object_t *Object, - DWORD Access, - BOOL Inheritable); -typedef NTSTATUS (WINAPI *CSRSS_GET_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access); -typedef NTSTATUS (WINAPI *CSRSS_RELEASE_OBJECT_BY_POINTER_PROC)(Object_t *Object); -typedef NTSTATUS (WINAPI *CSRSS_RELEASE_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Object ); typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESSES_PROC)(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context); typedef struct tagCSRSS_EXPORTED_FUNCS { - CSRSS_INSERT_OBJECT_PROC CsrInsertObjectProc; - CSRSS_GET_OBJECT_PROC CsrGetObjectProc; - CSRSS_RELEASE_OBJECT_BY_POINTER_PROC CsrReleaseObjectByPointerProc; - CSRSS_RELEASE_OBJECT_PROC CsrReleaseObjectProc; CSRSS_ENUM_PROCESSES_PROC CsrEnumProcessesProc; } CSRSS_EXPORTED_FUNCS, *PCSRSS_EXPORTED_FUNCS; @@ -50,10 +34,21 @@ typedef BOOL (WINAPI *CSRPLUGIN_INIT_COMPLETE_PROC)(void); typedef BOOL (WINAPI *CSRPLUGIN_HARDERROR_PROC)(IN PCSRSS_PROCESS_DATA ProcessData, IN PHARDERROR_MSG HardErrorMessage); +typedef NTSTATUS (WINAPI *CSRPLUGIN_PROCESS_INHERIT_PROC)(IN PCSRSS_PROCESS_DATA SourceProcessData, + IN PCSRSS_PROCESS_DATA TargetProcessData); + +typedef NTSTATUS (WINAPI *CSRPLUGIN_PROCESS_DELETED_PROC)(IN PCSRSS_PROCESS_DATA ProcessData); + +typedef struct tagCSRSS_SERVER_PROCS +{ + CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc; + CSRPLUGIN_HARDERROR_PROC HardErrorProc; + CSRPLUGIN_PROCESS_INHERIT_PROC ProcessInheritProc; + CSRPLUGIN_PROCESS_DELETED_PROC ProcessDeletedProc; +} CSRPLUGIN_SERVER_PROCS, *PCSRPLUGIN_SERVER_PROCS; + typedef BOOL (WINAPI *CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions, - PCSRSS_OBJECT_DEFINITION *ObjectDefinitions, - CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProc, - CSRPLUGIN_HARDERROR_PROC *HardErrorProc, + PCSRPLUGIN_SERVER_PROCS ServerProcs, PCSRSS_EXPORTED_FUNCS Exports, HANDLE CsrssApiHeap); diff --git a/subsystems/win32/csrss/include/win32csr.h b/subsystems/win32/csrss/include/win32csr.h deleted file mode 100644 index 6b7791f72f6..00000000000 --- a/subsystems/win32/csrss/include/win32csr.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: subsys/csrss/win32csr/win32csr.h - * PURPOSE: Interface to win32csr.dll - */ - -#pragma once - -#include -#include - -extern HANDLE Win32CsrApiHeap; -extern HINSTANCE Win32CsrDllHandle; - -NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, - PHANDLE Handle, - Object_t *Object, - DWORD Access, - BOOL Inheritable); -NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access, - long Type); -VOID FASTCALL Win32CsrUnlockObject(Object_t *Object); - -NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access); -NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object); -NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Object); -NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, - PVOID Context); - -/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/alias.c b/subsystems/win32/csrss/win32csr/alias.c index 1432be1be53..74159544440 100644 --- a/subsystems/win32/csrss/win32csr/alias.c +++ b/subsystems/win32/csrss/win32csr/alias.c @@ -5,7 +5,7 @@ * PURPOSE: CSRSS alias support functions * COPYRIGHT: Christoph Wittich * Johannes Anderwald - * + * */ @@ -17,10 +17,10 @@ typedef struct tagALIAS_ENTRY { - LPCWSTR lpSource; - LPCWSTR lpTarget; - struct tagALIAS_ENTRY * Next; -}ALIAS_ENTRY, *PALIAS_ENTRY; + LPCWSTR lpSource; + LPCWSTR lpTarget; + struct tagALIAS_ENTRY * Next; +} ALIAS_ENTRY, *PALIAS_ENTRY; typedef struct tagALIAS_HEADER @@ -29,22 +29,7 @@ typedef struct tagALIAS_HEADER PALIAS_ENTRY Data; struct tagALIAS_HEADER * Next; -}ALIAS_HEADER, *PALIAS_HEADER; - -/* Ensure that a buffer is contained within the process's shared memory section. */ -static BOOL -ValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, ULONG Size) -{ - ULONG Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; - if (Offset >= ProcessData->CsrSectionViewSize - || Size > (ProcessData->CsrSectionViewSize - Offset)) - { - DPRINT1("Invalid buffer %p %d; not within %p %d\n", - Buffer, Size, ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); - return FALSE; - } - return TRUE; -} +} ALIAS_HEADER, *PALIAS_HEADER; static PALIAS_HEADER @@ -67,38 +52,38 @@ IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName) PALIAS_HEADER IntCreateAliasHeader(LPCWSTR lpExeName) { - PALIAS_HEADER Entry; - UINT dwLength = wcslen(lpExeName) + 1; + PALIAS_HEADER Entry; + UINT dwLength = wcslen(lpExeName) + 1; - Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength); - if (!Entry) - return Entry; - - Entry->lpExeName = (LPCWSTR)(Entry + 1); - wcscpy((WCHAR*)Entry->lpExeName, lpExeName); - Entry->Data = NULL; - Entry->Next = NULL; - return Entry; + Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength); + if (!Entry) + return Entry; + + Entry->lpExeName = (LPCWSTR)(Entry + 1); + wcscpy((WCHAR*)Entry->lpExeName, lpExeName); + Entry->Data = NULL; + Entry->Next = NULL; + return Entry; } VOID IntInsertAliasHeader(PALIAS_HEADER * RootHeader, PALIAS_HEADER NewHeader) { - PALIAS_HEADER CurrentHeader; - PALIAS_HEADER *LastLink = RootHeader; + PALIAS_HEADER CurrentHeader; + PALIAS_HEADER *LastLink = RootHeader; - while ((CurrentHeader = *LastLink) != NULL) - { - INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName); - if (Diff < 0) - { - break; - } - LastLink = &CurrentHeader->Next; - } + while ((CurrentHeader = *LastLink) != NULL) + { + INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName); + if (Diff < 0) + { + break; + } + LastLink = &CurrentHeader->Next; + } - *LastLink = NewHeader; - NewHeader->Next = CurrentHeader; + *LastLink = NewHeader; + NewHeader->Next = CurrentHeader; } PALIAS_ENTRY @@ -130,60 +115,60 @@ IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName) VOID IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry) { - PALIAS_ENTRY CurrentEntry; - PALIAS_ENTRY *LastLink = &Header->Data; + PALIAS_ENTRY CurrentEntry; + PALIAS_ENTRY *LastLink = &Header->Data; - while ((CurrentEntry = *LastLink) != NULL) - { - INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource); - if (Diff < 0) + while ((CurrentEntry = *LastLink) != NULL) { - break; + INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource); + if (Diff < 0) + { + break; + } + LastLink = &CurrentEntry->Next; } - LastLink = &CurrentEntry->Next; - } - *LastLink = NewEntry; - NewEntry->Next = CurrentEntry; + *LastLink = NewEntry; + NewEntry->Next = CurrentEntry; } PALIAS_ENTRY IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget) { - UINT dwSource; - UINT dwTarget; - PALIAS_ENTRY Entry; + UINT dwSource; + UINT dwTarget; + PALIAS_ENTRY Entry; - dwSource = wcslen(lpSource) + 1; - dwTarget = wcslen(lpTarget) + 1; + dwSource = wcslen(lpSource) + 1; + dwTarget = wcslen(lpTarget) + 1; - Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget)); - if (!Entry) - return Entry; + Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget)); + if (!Entry) + return Entry; - Entry->lpSource = (LPCWSTR)(Entry + 1); - wcscpy((LPWSTR)Entry->lpSource, lpSource); - Entry->lpTarget = Entry->lpSource + dwSource; - wcscpy((LPWSTR)Entry->lpTarget, lpTarget); - Entry->Next = NULL; + Entry->lpSource = (LPCWSTR)(Entry + 1); + wcscpy((LPWSTR)Entry->lpSource, lpSource); + Entry->lpTarget = Entry->lpSource + dwSource; + wcscpy((LPWSTR)Entry->lpTarget, lpTarget); + Entry->Next = NULL; - return Entry; + return Entry; } UINT IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader) { - UINT length = 0; + UINT length = 0; - while(RootHeader) - { - length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR); - RootHeader = RootHeader->Next; - } - if (length) - length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes + while(RootHeader) + { + length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR); + RootHeader = RootHeader->Next; + } + if (length) + length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes - return length; + return length; } UINT @@ -215,22 +200,22 @@ IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT Tar UINT IntGetAllConsoleAliasesLength(PALIAS_HEADER Header) { - UINT Length = 0; - PALIAS_ENTRY CurEntry = Header->Data; + UINT Length = 0; + PALIAS_ENTRY CurEntry = Header->Data; - while(CurEntry) - { - Length += wcslen(CurEntry->lpSource); - Length += wcslen(CurEntry->lpTarget); - Length += 2; // zero byte and '=' - CurEntry = CurEntry->Next; - } + while(CurEntry) + { + Length += wcslen(CurEntry->lpSource); + Length += wcslen(CurEntry->lpTarget); + Length += 2; // zero byte and '=' + CurEntry = CurEntry->Next; + } - if (Length) - { - return (Length+1) * sizeof(WCHAR); - } - return 0; + if (Length) + { + return (Length+1) * sizeof(WCHAR); + } + return 0; } UINT IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength) @@ -316,7 +301,7 @@ CSR_API(CsrAddConsoleAlias) { return STATUS_INVALID_PARAMETER; } - + Request->Status = ConioConsoleFromProcessData(ProcessData, &Console); if (!NT_SUCCESS(Request->Status)) { @@ -379,11 +364,11 @@ CSR_API(CsrGetConsoleAlias) lpTarget = Request->Data.GetConsoleAlias.TargetBuffer; - DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n", - lpExeName, lpSource, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength); - - if (Request->Data.GetConsoleAlias.ExeLength == 0 || lpTarget == NULL || - Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.SourceLength == 0) + DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n", + lpExeName, lpSource, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength); + + if (Request->Data.GetConsoleAlias.ExeLength == 0 || lpTarget == NULL || + Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.SourceLength == 0) { return STATUS_INVALID_PARAMETER; } @@ -415,7 +400,8 @@ CSR_API(CsrGetConsoleAlias) return STATUS_BUFFER_TOO_SMALL; } - if (!ValidateBuffer(ProcessData, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength)) + if (!Win32CsrValidateBuffer(ProcessData, lpTarget, + Request->Data.GetConsoleAlias.TargetBufferLength, 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; @@ -457,15 +443,16 @@ CSR_API(CsrGetAllConsoleAliases) return STATUS_BUFFER_OVERFLOW; } - if (!ValidateBuffer(ProcessData, - Request->Data.GetAllConsoleAlias.AliasBuffer, - Request->Data.GetAllConsoleAlias.AliasBufferLength)) + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetAllConsoleAlias.AliasBuffer, + Request->Data.GetAllConsoleAlias.AliasBufferLength, + 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; } - BytesWritten = IntGetAllConsoleAliases(Header, + BytesWritten = IntGetAllConsoleAliases(Header, Request->Data.GetAllConsoleAlias.AliasBuffer, Request->Data.GetAllConsoleAlias.AliasBufferLength); @@ -509,7 +496,7 @@ CSR_API(CsrGetConsoleAliasesExes) PCSRSS_CONSOLE Console; UINT BytesWritten; UINT ExesLength; - + DPRINT("CsrGetConsoleAliasesExes entered\n"); Request->Status = ConioConsoleFromProcessData(ProcessData, &Console); @@ -519,7 +506,7 @@ CSR_API(CsrGetConsoleAliasesExes) } ExesLength = IntGetConsoleAliasesExesLength(Console->Aliases); - + if (ExesLength > Request->Data.GetConsoleAliasesExes.Length) { ConioUnlockConsole(Console); @@ -531,16 +518,17 @@ CSR_API(CsrGetConsoleAliasesExes) ConioUnlockConsole(Console); return STATUS_INVALID_PARAMETER; } - - if (!ValidateBuffer(ProcessData, - Request->Data.GetConsoleAliasesExes.ExeNames, - Request->Data.GetConsoleAliasesExes.Length)) + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetConsoleAliasesExes.ExeNames, + Request->Data.GetConsoleAliasesExes.Length, + 1)) { ConioUnlockConsole(Console); return STATUS_ACCESS_VIOLATION; } - BytesWritten = IntGetConsoleAliasesExes(Console->Aliases, + BytesWritten = IntGetConsoleAliasesExes(Console->Aliases, Request->Data.GetConsoleAliasesExes.ExeNames, Request->Data.GetConsoleAliasesExes.Length); diff --git a/subsystems/win32/csrss/win32csr/appswitch.c b/subsystems/win32/csrss/win32csr/appswitch.c index 3d372a199f1..f816a8303ad 100644 --- a/subsystems/win32/csrss/win32csr/appswitch.c +++ b/subsystems/win32/csrss/win32csr/appswitch.c @@ -19,7 +19,7 @@ typedef struct APPSWITCH_ITEM BOOL bFocus; struct APPSWITCH_ITEM * Next; WCHAR szText[1]; -}APPSWITCH_ITEM, *PAPPSWITCH_ITEM; +} APPSWITCH_ITEM, *PAPPSWITCH_ITEM; static PAPPSWITCH_ITEM pRoot = NULL; static DWORD NumOfWindows = 0; @@ -30,7 +30,7 @@ UINT WINAPI PrivateExtractIconExW(LPCWSTR,int,HICON*,HICON*,UINT); BOOL -CALLBACK +CALLBACK EnumWindowEnumProc( HWND hwnd, LPARAM lParam @@ -51,21 +51,21 @@ EnumWindowEnumProc( hIcon = (HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0); if (!hIcon) { - GetWindowThreadProcessId(hwnd, &dwPid); - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, dwPid); - if (hProcess) - { - if (GetModuleFileNameExW(hProcess, NULL, szFileName, MAX_PATH)) - { - szFileName[MAX_PATH-1] = L'\0'; - PrivateExtractIconExW(szFileName, 0, &hIcon, NULL, 1); - } - } + GetWindowThreadProcessId(hwnd, &dwPid); + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, dwPid); + if (hProcess) + { + if (GetModuleFileNameExW(hProcess, NULL, szFileName, MAX_PATH)) + { + szFileName[MAX_PATH-1] = L'\0'; + PrivateExtractIconExW(szFileName, 0, &hIcon, NULL, 1); + } + } } else { - /* icons from WM_GETICON need to be copied */ - hIcon = CopyIcon(hIcon); + /* icons from WM_GETICON need to be copied */ + hIcon = CopyIcon(hIcon); } /* get the text length */ Length = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); @@ -88,9 +88,9 @@ EnumWindowEnumProc( if (!pRoot) { - /* first item */ - pRoot = pItem; - return TRUE; + /* first item */ + pRoot = pItem; + return TRUE; } /* enumerate the last item */ @@ -107,16 +107,16 @@ EnumWindowEnumProc( VOID EnumerateAppWindows(HDESK hDesk, HWND hwndDlg) { - /* initialize defaults */ - pRoot = NULL; - NumOfWindows = 0; - hAppWindowDlg = hwndDlg; - /* enumerate all windows */ - EnumDesktopWindows(hDesk, EnumWindowEnumProc, (LPARAM)NULL); - if (NumOfWindows > 7) - { - /* FIXME resize window */ - } + /* initialize defaults */ + pRoot = NULL; + NumOfWindows = 0; + hAppWindowDlg = hwndDlg; + /* enumerate all windows */ + EnumDesktopWindows(hDesk, EnumWindowEnumProc, (LPARAM)NULL); + if (NumOfWindows > 7) + { + /* FIXME resize window */ + } } VOID @@ -126,7 +126,7 @@ MarkNextEntryAsActive() pItem = pRoot; if (!pRoot) - return; + return; while(pItem) { @@ -153,82 +153,82 @@ KeyboardHookProc( LPARAM lParam ) { - PKBDLLHOOKSTRUCT hk = (PKBDLLHOOKSTRUCT) lParam; + PKBDLLHOOKSTRUCT hk = (PKBDLLHOOKSTRUCT) lParam; - if (wParam == WM_SYSKEYUP) - { - /* is tab key pressed */ - if (hk->vkCode == VK_TAB) - { - if (hAppWindowDlg == NULL) - { - /* FIXME - * launch window - */ - DPRINT1("launch alt-tab window\n"); - } - else - { - MarkNextEntryAsActive(); - } - } - } - return CallNextHookEx(hhk, nCode, wParam, lParam); + if (wParam == WM_SYSKEYUP) + { + /* is tab key pressed */ + if (hk->vkCode == VK_TAB) + { + if (hAppWindowDlg == NULL) + { + /* FIXME + * launch window + */ + DPRINT1("launch alt-tab window\n"); + } + else + { + MarkNextEntryAsActive(); + } + } + } + return CallNextHookEx(hhk, nCode, wParam, lParam); } VOID PaintAppWindows(HWND hwndDlg, HDC hDc) { - DWORD dwIndex, X, Y; - PAPPSWITCH_ITEM pCurItem; - RECT Rect; - DWORD XSize, YSize, XMax; - HBRUSH hBrush; + DWORD dwIndex, X, Y; + PAPPSWITCH_ITEM pCurItem; + RECT Rect; + DWORD XSize, YSize, XMax; + HBRUSH hBrush; - X = 10; - Y = 10; - XSize = GetSystemMetrics(SM_CXICON); - YSize = GetSystemMetrics(SM_CYICON); - XMax = (XSize+(XSize/2)) * 7 + X; - pCurItem = pRoot; + X = 10; + Y = 10; + XSize = GetSystemMetrics(SM_CXICON); + YSize = GetSystemMetrics(SM_CYICON); + XMax = (XSize+(XSize/2)) * 7 + X; + pCurItem = pRoot; - for (dwIndex = 0; dwIndex < NumOfWindows; dwIndex++) - { - if (X >= XMax) - { - X = 10; - Y += YSize + (YSize/2); - } - if (pCurItem->bFocus) - { + for (dwIndex = 0; dwIndex < NumOfWindows; dwIndex++) + { + if (X >= XMax) + { + X = 10; + Y += YSize + (YSize/2); + } + if (pCurItem->bFocus) + { hBrush = CreateSolidBrush(RGB(30, 30, 255)); SetRect(&Rect, X-5, Y-5, X + XSize + 5, Y + YSize + 5); FillRect(hDc, &Rect, hBrush); DeleteObject((HGDIOBJ)hBrush); SendDlgItemMessageW(hwndDlg, IDC_STATIC_CUR_APP, WM_SETTEXT, 0, (LPARAM)pCurItem->szText); - } + } - DrawIcon(hDc, X, Y, pCurItem->hIcon); - pCurItem = pCurItem->Next; - X += XSize +(XSize/2); - } + DrawIcon(hDc, X, Y, pCurItem->hIcon); + pCurItem = pCurItem->Next; + X += XSize +(XSize/2); + } } VOID DestroyAppWindows() { - PAPPSWITCH_ITEM pCurItem, pNextItem; + PAPPSWITCH_ITEM pCurItem, pNextItem; - pCurItem = pRoot; - while(pCurItem) - { - pNextItem = pCurItem->Next; - DestroyIcon(pCurItem->hIcon); - HeapFree(Win32CsrApiHeap, 0, pCurItem); - pCurItem = pNextItem; - } - pRoot = NULL; - hAppWindowDlg = NULL; - NumOfWindows = 0; + pCurItem = pRoot; + while(pCurItem) + { + pNextItem = pCurItem->Next; + DestroyIcon(pCurItem->hIcon); + HeapFree(Win32CsrApiHeap, 0, pCurItem); + pCurItem = pNextItem; + } + pRoot = NULL; + hAppWindowDlg = NULL; + NumOfWindows = 0; } INT_PTR diff --git a/subsystems/win32/csrss/win32csr/coninput.c b/subsystems/win32/csrss/win32csr/coninput.c new file mode 100644 index 00000000000..fa770aaade3 --- /dev/null +++ b/subsystems/win32/csrss/win32csr/coninput.c @@ -0,0 +1,638 @@ +/* + * reactos/subsys/csrss/win32csr/conio.c + * + * Console I/O functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +/* GLOBALS *******************************************************************/ + +#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) + +/* FUNCTIONS *****************************************************************/ + +CSR_API(CsrReadConsole) +{ + PLIST_ENTRY CurrentEntry; + ConsoleInput *Input; + PCHAR Buffer; + PWCHAR UnicodeBuffer; + ULONG i = 0; + ULONG nNumberOfCharsToRead, CharSize; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrReadConsole\n"); + + CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */ + nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Buffer = (PCHAR)Request->Data.ReadConsoleRequest.Buffer; + UnicodeBuffer = (PWCHAR)Buffer; + Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, + &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; + + Status = STATUS_PENDING; /* we haven't read anything (yet) */ + if (Console->Mode & ENABLE_LINE_INPUT) + { + if (Console->LineBuffer == NULL) + { + /* Starting a new line */ + Console->LineMaxSize = max(256, Request->Data.ReadConsoleRequest.FullReadSize); + Console->LineBuffer = HeapAlloc(Win32CsrApiHeap, 0, Console->LineMaxSize * sizeof(WCHAR)); + if (Console->LineBuffer == NULL) + { + Status = STATUS_NO_MEMORY; + goto done; + } + Console->LineComplete = FALSE; + Console->LineSize = 0; + Console->LinePos = 0; + Console->LineUpPressed = FALSE; + } + + /* If we don't have a complete line yet, process the pending input */ + while (!Console->LineComplete && !IsListEmpty(&Console->InputEvents)) + { + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown) + { + LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); + } + HeapFree(Win32CsrApiHeap, 0, Input); + } + + /* Check if we have a complete line to read from */ + if (Console->LineComplete) + { + while (i < nNumberOfCharsToRead && Console->LinePos != Console->LineSize) + { + WCHAR Char = Console->LineBuffer[Console->LinePos++]; + if (Request->Data.ReadConsoleRequest.Unicode) + UnicodeBuffer[i++] = Char; + else + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char); + } + if (Console->LinePos == Console->LineSize) + { + HeapFree(Win32CsrApiHeap, 0, Console->LineBuffer); + Console->LineBuffer = NULL; + Status = STATUS_SUCCESS; /* Entire line has been read */ + } + } + } + else + { + /* Character input */ + while (i < nNumberOfCharsToRead && !IsListEmpty(&Console->InputEvents)) + { + /* remove input event from queue */ + CurrentEntry = RemoveHeadList(&Console->InputEvents); + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* only pay attention to valid ascii chars, on key down */ + if (KEY_EVENT == Input->InputEvent.EventType + && Input->InputEvent.Event.KeyEvent.bKeyDown + && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') + { + WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; + if (Request->Data.ReadConsoleRequest.Unicode) + UnicodeBuffer[i++] = Char; + else + ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char); + Status = STATUS_SUCCESS; /* did read something */ + } + HeapFree(Win32CsrApiHeap, 0, Input); + } + } +done: + Request->Data.ReadConsoleRequest.NrCharactersRead = i; + ConioUnlockConsole(Console); + + if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize; + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + } + + return Status; +} + +static VOID FASTCALL +ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent) +{ + if (InputEvent->EventType == KEY_EVENT) + { + WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; + InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; + ConsoleInputUnicodeCharToAnsiChar(Console, + &InputEvent->Event.KeyEvent.uChar.AsciiChar, + &UnicodeChar); + } +} + +static NTSTATUS FASTCALL +ConioProcessChar(PCSRSS_CONSOLE Console, + PINPUT_RECORD InputEvent) +{ + /* Check for pause or unpause */ + if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) + { + WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode; + if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) + { + DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState; + if (Console->Mode & ENABLE_LINE_INPUT && + (vk == VK_PAUSE || (vk == 'S' && + (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && + !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) + { + ConioPause(Console, PAUSED_FROM_KEYBOARD); + return STATUS_SUCCESS; + } + } + else + { + if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && + vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) + { + ConioUnpause(Console, PAUSED_FROM_KEYBOARD); + return STATUS_SUCCESS; + } + } + } + + /* add event to the queue */ + ConsoleInput *ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); + if (ConInRec == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + ConInRec->InputEvent = *InputEvent; + InsertTailList(&Console->InputEvents, &ConInRec->ListEntry); + SetEvent(Console->ActiveEvent); + return STATUS_SUCCESS; +} + +static DWORD FASTCALL +ConioGetShiftState(PBYTE KeyState) +{ + DWORD ssOut = 0; + + if (KeyState[VK_CAPITAL] & 1) + ssOut |= CAPSLOCK_ON; + + if (KeyState[VK_NUMLOCK] & 1) + ssOut |= NUMLOCK_ON; + + if (KeyState[VK_SCROLL] & 1) + ssOut |= SCROLLLOCK_ON; + + if (KeyState[VK_SHIFT] & 0x80) + ssOut |= SHIFT_PRESSED; + + if (KeyState[VK_LCONTROL] & 0x80) + ssOut |= LEFT_CTRL_PRESSED; + if (KeyState[VK_RCONTROL] & 0x80) + ssOut |= RIGHT_CTRL_PRESSED; + + if (KeyState[VK_LMENU] & 0x80) + ssOut |= LEFT_ALT_PRESSED; + if (KeyState[VK_RMENU] & 0x80) + ssOut |= RIGHT_ALT_PRESSED; + + return ssOut; +} + +VOID WINAPI +ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) +{ + static BYTE KeyState[256] = { 0 }; + /* MSDN mentions that you should use the last virtual key code received + * when putting a virtual key identity to a WM_CHAR message since multiple + * or translated keys may be involved. */ + static UINT LastVirtualKey = 0; + DWORD ShiftState; + UINT RepeatCount; + WCHAR UnicodeChar; + UINT VirtualKeyCode; + UINT VirtualScanCode; + BOOL Down = FALSE; + INPUT_RECORD er; + BOOLEAN Fake; // synthesized, not a real event + BOOLEAN NotChar; // message should not be used to return a character + + RepeatCount = 1; + VirtualScanCode = (msg->lParam >> 16) & 0xff; + Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || + msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; + + GetKeyboardState(KeyState); + ShiftState = ConioGetShiftState(KeyState); + + if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) + { + VirtualKeyCode = LastVirtualKey; + UnicodeChar = msg->wParam; + } + else + { + WCHAR Chars[2]; + INT RetChars = 0; + + VirtualKeyCode = msg->wParam; + RetChars = ToUnicodeEx(VirtualKeyCode, + VirtualScanCode, + KeyState, + Chars, + 2, + 0, + 0); + UnicodeChar = (1 == RetChars ? Chars[0] : 0); + } + + er.EventType = KEY_EVENT; + er.Event.KeyEvent.bKeyDown = Down; + er.Event.KeyEvent.wRepeatCount = RepeatCount; + er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; + er.Event.KeyEvent.dwControlKeyState = ShiftState; + er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; + er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; + + if (TextMode) + { + if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + && VK_TAB == VirtualKeyCode) + { + if (Down) + { + TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); + } + + return; + } + else if (VK_MENU == VirtualKeyCode && ! Down) + { + if (TuiSwapConsole(0)) + { + return; + } + } + } + + if (NULL == Console) + { + DPRINT1("No Active Console!\n"); + return; + } + + Fake = UnicodeChar && + (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && + msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); + NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); + if (NotChar) + LastVirtualKey = msg->wParam; + + DPRINT ("csrss: %s %s %s %s %02x %02x '%lc' %04x\n", + Down ? "down" : "up ", + (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? + "char" : "key ", + Fake ? "fake" : "real", + NotChar ? "notc" : "char", + VirtualScanCode, + VirtualKeyCode, + (UnicodeChar >= L' ') ? UnicodeChar : L'.', + ShiftState); + + if (Fake) + return; + + /* process Ctrl-C and Ctrl-Break */ + if (Console->Mode & ENABLE_PROCESSED_INPUT && + er.Event.KeyEvent.bKeyDown && + ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || + (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && + (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))) + { + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + DPRINT1("Console_Api Ctrl-C\n"); + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + current_entry = current_entry->Flink; + ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); + } + return; + } + + if (0 != (er.Event.KeyEvent.dwControlKeyState + & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode + || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) + { + if (er.Event.KeyEvent.bKeyDown) + { + /* scroll up or down */ + if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) + { + /* only scroll up if there is room to scroll up into */ + if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + + Console->ActiveBuffer->MaxY - 1) % + Console->ActiveBuffer->MaxY; + Console->ActiveBuffer->CurrentY++; + } + } + else + { + /* only scroll down if there is room to scroll down into */ + if (Console->ActiveBuffer->CurrentY != 0) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % + Console->ActiveBuffer->MaxY; + Console->ActiveBuffer->CurrentY--; + } + } + ConioDrawConsole(Console); + } + return; + } + ConioProcessChar(Console, &er); +} + +CSR_API(CsrReadInputEvent) +{ + PLIST_ENTRY CurrentEntry; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + BOOLEAN Done = FALSE; + ConsoleInput *Input; + + DPRINT("CsrReadInputEvent\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent; + + Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + /* only get input if there is any */ + CurrentEntry = Console->InputEvents.Flink; + while (CurrentEntry != &Console->InputEvents) + { + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + CurrentEntry = CurrentEntry->Flink; + + if (Done) + { + Request->Data.ReadInputRequest.MoreEvents = TRUE; + break; + } + + RemoveEntryList(&Input->ListEntry); + + if (!Done) + { + Request->Data.ReadInputRequest.Input = Input->InputEvent; + if (Request->Data.ReadInputRequest.Unicode == FALSE) + { + ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input); + } + Done = TRUE; + } + + HeapFree(Win32CsrApiHeap, 0, Input); + } + + if (Done) + Status = STATUS_SUCCESS; + else + Status = STATUS_PENDING; + + if (IsListEmpty(&Console->InputEvents)) + { + ResetEvent(Console->ActiveEvent); + } + + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrFlushInputBuffer) +{ + PLIST_ENTRY CurrentEntry; + PCSRSS_CONSOLE Console; + ConsoleInput* Input; + NTSTATUS Status; + + DPRINT("CsrFlushInputBuffer\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockConsole(ProcessData, + Request->Data.FlushInputBufferRequest.ConsoleInput, + &Console, + GENERIC_WRITE); + if(! NT_SUCCESS(Status)) + { + return Status; + } + + /* Discard all entries in the input event queue */ + while (!IsListEmpty(&Console->InputEvents)) + { + CurrentEntry = RemoveHeadList(&Console->InputEvents); + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + /* Destroy the event */ + HeapFree(Win32CsrApiHeap, 0, Input); + } + ResetEvent(Console->ActiveEvent); + + ConioUnlockConsole(Console); + + return STATUS_SUCCESS; +} + +CSR_API(CsrGetNumberOfConsoleInputEvents) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PLIST_ENTRY CurrentItem; + DWORD NumEvents; + + DPRINT("CsrGetNumberOfConsoleInputEvents\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + CurrentItem = Console->InputEvents.Flink; + NumEvents = 0; + + /* If there are any events ... */ + while (CurrentItem != &Console->InputEvents) + { + CurrentItem = CurrentItem->Flink; + NumEvents++; + } + + ConioUnlockConsole(Console); + + Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents; + + return STATUS_SUCCESS; +} + +CSR_API(CsrPeekConsoleInput) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + DWORD Length; + PLIST_ENTRY CurrentItem; + PINPUT_RECORD InputRecord; + ConsoleInput* Item; + UINT NumItems; + + DPRINT("CsrPeekConsoleInput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); + if(! NT_SUCCESS(Status)) + { + return Status; + } + + InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; + Length = Request->Data.PeekConsoleInputRequest.Length; + + if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD))) + { + ConioUnlockConsole(Console); + return STATUS_ACCESS_VIOLATION; + } + + NumItems = 0; + + if (! IsListEmpty(&Console->InputEvents)) + { + CurrentItem = Console->InputEvents.Flink; + + while (CurrentItem != &Console->InputEvents && NumItems < Length) + { + Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); + + ++NumItems; + *InputRecord = Item->InputEvent; + + if (Request->Data.PeekConsoleInputRequest.Unicode == FALSE) + { + ConioInputEventToAnsi(Console, InputRecord); + } + + InputRecord++; + CurrentItem = CurrentItem->Flink; + } + } + + ConioUnlockConsole(Console); + + Request->Data.PeekConsoleInputRequest.Length = NumItems; + + return STATUS_SUCCESS; +} + +CSR_API(CsrWriteConsoleInput) +{ + PINPUT_RECORD InputRecord; + PCSRSS_CONSOLE Console; + NTSTATUS Status; + DWORD Length; + DWORD i; + + DPRINT("CsrWriteConsoleInput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; + Length = Request->Data.WriteConsoleInputRequest.Length; + + if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD))) + { + ConioUnlockConsole(Console); + return STATUS_ACCESS_VIOLATION; + } + + for (i = 0; i < Length && NT_SUCCESS(Status); i++) + { + if (!Request->Data.WriteConsoleInputRequest.Unicode && + InputRecord->EventType == KEY_EVENT) + { + CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; + ConsoleInputAnsiCharToUnicodeChar(Console, + &InputRecord->Event.KeyEvent.uChar.UnicodeChar, + &AsciiChar); + } + Status = ConioProcessChar(Console, InputRecord++); + } + + ConioUnlockConsole(Console); + + Request->Data.WriteConsoleInputRequest.Length = i; + + return Status; +} + +/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/conio.c b/subsystems/win32/csrss/win32csr/conio.c deleted file mode 100644 index 493ac172db0..00000000000 --- a/subsystems/win32/csrss/win32csr/conio.c +++ /dev/null @@ -1,3153 +0,0 @@ -/* - * reactos/subsys/csrss/win32csr/conio.c - * - * Console I/O functions - * - * ReactOS Operating System - */ - -/* INCLUDES ******************************************************************/ - -#define NDEBUG -#include "w32csr.h" -#include - -/* GLOBALS *******************************************************************/ - -#define ConioInitRect(Rect, Top, Left, Bottom, Right) \ - ((Rect)->top) = Top; \ - ((Rect)->left) = Left; \ - ((Rect)->bottom) = Bottom; \ - ((Rect)->right) = Right - -#define ConioIsRectEmpty(Rect) \ - (((Rect)->left > (Rect)->right) || ((Rect)->top > (Rect)->bottom)) - -#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) - -#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) - -#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) - -#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) - - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS FASTCALL -ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console) -{ - PCSRSS_CONSOLE ProcessConsole = ProcessData->Console; - - if (!ProcessConsole) - { - *Console = NULL; - return STATUS_INVALID_HANDLE; - } - - InterlockedIncrement(&ProcessConsole->Header.ReferenceCount); - EnterCriticalSection(&(ProcessConsole->Header.Lock)); - *Console = ProcessConsole; - - return STATUS_SUCCESS; -} - -VOID FASTCALL -ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD Timeout) -{ - HANDLE Thread; - - DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId); - - if (ProcessData->CtrlDispatcher) - { - - Thread = CreateRemoteThread(ProcessData->Process, NULL, 0, - (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher, - UlongToPtr(Event), 0, NULL); - if (NULL == Thread) - { - DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); - return; - } - WaitForSingleObject(Thread, Timeout); - CloseHandle(Thread); - } -} - -VOID FASTCALL -ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData) -{ - ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); -} - -PBYTE FASTCALL -ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y) -{ - return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; -} - -static VOID FASTCALL -ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff) -{ - PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); - UINT Pos; - - for (Pos = 0; Pos < Buff->MaxX; Pos++) - { - /* Fill the cell */ - *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; - } -} - -static NTSTATUS FASTCALL -CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, - PCSRSS_SCREEN_BUFFER Buffer) -{ - DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); - - Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; - Buffer->Header.ReferenceCount = 0; - Buffer->ShowX = 0; - Buffer->ShowY = 0; - Buffer->VirtualY = 0; - Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); - if (NULL == Buffer->Buffer) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - InitializeCriticalSection(&Buffer->Header.Lock); - ConioInitScreenBuffer(Console, Buffer); - /* initialize buffer to be empty with default attributes */ - for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) - { - ClearLineBuffer(Buffer); - } - Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; - Buffer->CurrentX = 0; - Buffer->CurrentY = 0; - - return STATUS_SUCCESS; -} - -static NTSTATUS WINAPI -CsrInitConsole(PCSRSS_CONSOLE Console) -{ - NTSTATUS Status; - SECURITY_ATTRIBUTES SecurityAttributes; - PCSRSS_SCREEN_BUFFER NewBuffer; - BOOL GuiMode; - - Console->Title.MaximumLength = Console->Title.Length = 0; - Console->Title.Buffer = NULL; - - //FIXME - RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); - - Console->Header.ReferenceCount = 0; - Console->WaitingChars = 0; - Console->WaitingLines = 0; - Console->EchoCount = 0; - Console->Header.Type = CONIO_CONSOLE_MAGIC; - Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; - Console->EarlyReturn = FALSE; - Console->ActiveBuffer = NULL; - InitializeListHead(&Console->InputEvents); - Console->CodePage = GetOEMCP(); - Console->OutputCodePage = GetOEMCP(); - - SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - SecurityAttributes.lpSecurityDescriptor = NULL; - SecurityAttributes.bInheritHandle = TRUE; - - Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); - if (NULL == Console->ActiveEvent) - { - RtlFreeUnicodeString(&Console->Title); - return STATUS_UNSUCCESSFUL; - } - Console->PrivateData = NULL; - InitializeCriticalSection(&Console->Header.Lock); - - GuiMode = DtbgIsDesktopVisible(); - - /* allocate console screen buffer */ - NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - if (NULL == NewBuffer) - { - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Header.Lock); - CloseHandle(Console->ActiveEvent); - return STATUS_INSUFFICIENT_RESOURCES; - } - /* init screen buffer with defaults */ - NewBuffer->CursorInfo.bVisible = TRUE; - NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - /* make console active, and insert into console list */ - Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; - - if (! GuiMode) - { - Status = TuiInitConsole(Console); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); - GuiMode = TRUE; - } - } - if (GuiMode) - { - Status = GuiInitConsole(Console); - if (! NT_SUCCESS(Status)) - { - HeapFree(Win32CsrApiHeap,0, NewBuffer); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Header.Lock); - CloseHandle(Console->ActiveEvent); - DPRINT1("GuiInitConsole: failed\n"); - return Status; - } - } - - Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); - if (! NT_SUCCESS(Status)) - { - ConioCleanupConsole(Console); - RtlFreeUnicodeString(&Console->Title); - DeleteCriticalSection(&Console->Header.Lock); - CloseHandle(Console->ActiveEvent); - HeapFree(Win32CsrApiHeap, 0, NewBuffer); - DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); - return Status; - } - - /* add a reference count because the buffer is tied to the console */ - InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount); - - /* copy buffer contents to screen */ - ConioDrawConsole(Console); - - return STATUS_SUCCESS; -} - - -CSR_API(CsrAllocConsole) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN NewConsole = FALSE; - - DPRINT("CsrAllocConsole\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (ProcessData->Console) - { - DPRINT1("Process already has a console\n"); - return STATUS_INVALID_PARAMETER; - } - - /* If we don't need a console, then get out of here */ - if (!Request->Data.AllocConsoleRequest.ConsoleNeeded) - { - DPRINT("No console needed\n"); - return STATUS_SUCCESS; - } - - /* If we already have one, then don't create a new one... */ - if (!Request->Data.AllocConsoleRequest.Console || - Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole) - { - /* Allocate a console structure */ - NewConsole = TRUE; - Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE)); - if (NULL == Console) - { - DPRINT1("Not enough memory for console\n"); - return STATUS_NO_MEMORY; - } - /* initialize list head */ - InitializeListHead(&Console->ProcessList); - /* insert process data required for GUI initialization */ - InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry); - /* Initialize the Console */ - Status = CsrInitConsole(Console); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Console init failed\n"); - HeapFree(Win32CsrApiHeap, 0, Console); - return Status; - } - } - else - { - /* Reuse our current console */ - Console = Request->Data.AllocConsoleRequest.Console; - } - - /* Set the Process Console */ - ProcessData->Console = Console; - - /* Return it to the caller */ - Request->Data.AllocConsoleRequest.Console = Console; - - /* Add a reference count because the process is tied to the console */ - Console->Header.ReferenceCount++; - - if (NewConsole || !ProcessData->bInheritHandles) - { - /* Insert the Objects */ - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.AllocConsoleRequest.InputHandle, - &Console->Header, - GENERIC_READ | GENERIC_WRITE, - TRUE); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed to insert object\n"); - ConioDeleteConsole((Object_t *) Console); - ProcessData->Console = 0; - return Status; - } - - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.AllocConsoleRequest.OutputHandle, - &Console->ActiveBuffer->Header, - GENERIC_READ | GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to insert object\n"); - ConioDeleteConsole((Object_t *) Console); - Win32CsrReleaseObject(ProcessData, - Request->Data.AllocConsoleRequest.InputHandle); - ProcessData->Console = 0; - return Status; - } - } - - /* Duplicate the Event */ - if (!DuplicateHandle(GetCurrentProcess(), - ProcessData->Console->ActiveEvent, - ProcessData->Process, - &ProcessData->ConsoleEvent, - EVENT_ALL_ACCESS, - FALSE, - 0)) - { - DPRINT1("DuplicateHandle() failed: %d\n", GetLastError); - ConioDeleteConsole((Object_t *) Console); - if (NewConsole || !ProcessData->bInheritHandles) - { - Win32CsrReleaseObject(ProcessData, - Request->Data.AllocConsoleRequest.OutputHandle); - Win32CsrReleaseObject(ProcessData, - Request->Data.AllocConsoleRequest.InputHandle); - } - ProcessData->Console = 0; - return Status; - } - - /* Set the Ctrl Dispatcher */ - ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher; - DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); - - if (!NewConsole) - { - /* Insert into the list if it has not been added */ - InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); - } - - return STATUS_SUCCESS; -} - -CSR_API(CsrFreeConsole) -{ - PCSRSS_CONSOLE Console; - - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (ProcessData->Console == NULL) - { - return STATUS_INVALID_PARAMETER; - } - - Console = ProcessData->Console; - ProcessData->Console = NULL; - RemoveEntryList(&ProcessData->ProcessEntry); - if (0 == InterlockedDecrement(&Console->Header.ReferenceCount)) - { - ConioDeleteConsole((Object_t *) Console); - } - return STATUS_SUCCESS; -} - -static VOID FASTCALL -ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, UINT *ScrolledLines) -{ - /* If we hit bottom, slide the viewable screen */ - if (++Buff->CurrentY == Buff->MaxY) - { - Buff->CurrentY--; - if (++Buff->VirtualY == Buff->MaxY) - { - Buff->VirtualY = 0; - } - (*ScrolledLines)++; - ClearLineBuffer(Buff); - if (UpdateRect->top != 0) - { - UpdateRect->top--; - } - } - UpdateRect->left = 0; - UpdateRect->right = Buff->MaxX - 1; - UpdateRect->bottom = Buff->CurrentY; -} - -static NTSTATUS FASTCALL -ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, - CHAR *Buffer, DWORD Length, BOOL Attrib) -{ - UINT i; - PBYTE Ptr; - RECT UpdateRect; - LONG CursorStartX, CursorStartY; - UINT ScrolledLines; - - CursorStartX = Buff->CurrentX; - CursorStartY = Buff->CurrentY; - UpdateRect.left = Buff->MaxX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = -1; - UpdateRect.bottom = Buff->CurrentY; - ScrolledLines = 0; - - for (i = 0; i < Length; i++) - { - if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) - { - /* --- LF --- */ - if (Buffer[i] == '\n') - { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - continue; - } - /* --- BS --- */ - else if (Buffer[i] == '\b') - { - /* Only handle BS if we're not on the first pos of the first line */ - if (0 != Buff->CurrentX || 0 != Buff->CurrentY) - { - if (0 == Buff->CurrentX) - { - /* slide virtual position up */ - Buff->CurrentX = Buff->MaxX - 1; - Buff->CurrentY--; - UpdateRect.top = min(UpdateRect.top, (LONG)Buff->CurrentY); - } - else - { - Buff->CurrentX--; - } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - Ptr[0] = ' '; - Ptr[1] = Buff->DefaultAttrib; - UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX); - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX); - } - continue; - } - /* --- CR --- */ - else if (Buffer[i] == '\r') - { - Buff->CurrentX = 0; - UpdateRect.left = min(UpdateRect.left, (LONG) Buff->CurrentX); - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX); - continue; - } - /* --- TAB --- */ - else if (Buffer[i] == '\t') - { - UINT EndX; - - UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX); - EndX = (Buff->CurrentX + 8) & ~7; - if (EndX > Buff->MaxX) - { - EndX = Buff->MaxX; - } - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - while (Buff->CurrentX < EndX) - { - *Ptr++ = ' '; - *Ptr++ = Buff->DefaultAttrib; - Buff->CurrentX++; - } - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX - 1); - if (Buff->CurrentX == Buff->MaxX) - { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) - { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - } - else - { - Buff->CurrentX--; - } - } - continue; - } - } - UpdateRect.left = min(UpdateRect.left, (LONG)Buff->CurrentX); - UpdateRect.right = max(UpdateRect.right, (LONG) Buff->CurrentX); - Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); - Ptr[0] = Buffer[i]; - if (Attrib) - { - Ptr[1] = Buff->DefaultAttrib; - } - Buff->CurrentX++; - if (Buff->CurrentX == Buff->MaxX) - { - if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) - { - Buff->CurrentX = 0; - ConioNextLine(Buff, &UpdateRect, &ScrolledLines); - } - else - { - Buff->CurrentX = CursorStartX; - } - } - } - - if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) - { - ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, - Buffer, Length); - } - - return STATUS_SUCCESS; -} - -CSR_API(CsrReadConsole) -{ - PLIST_ENTRY CurrentEntry; - ConsoleInput *Input; - PUCHAR Buffer; - PWCHAR UnicodeBuffer; - ULONG i; - ULONG nNumberOfCharsToRead, CharSize; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrReadConsole\n"); - - CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - /* truncate length to CSRSS_MAX_READ_CONSOLE_REQUEST */ - nNumberOfCharsToRead = min(Request->Data.ReadConsoleRequest.NrCharactersToRead, CSRSS_MAX_READ_CONSOLE / CharSize); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Buffer = Request->Data.ReadConsoleRequest.Buffer; - UnicodeBuffer = (PWCHAR)Buffer; - Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, - &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent; - for (i = 0; i < nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++) - { - /* remove input event from queue */ - CurrentEntry = RemoveHeadList(&Console->InputEvents); - if (IsListEmpty(&Console->InputEvents)) - { - ResetEvent(Console->ActiveEvent); - } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - - /* only pay attention to valid ascii chars, on key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\0') - { - /* - * backspace handling - if we are in charge of echoing it then we handle it here - * otherwise we treat it like a normal char. - */ - if ('\b' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar && 0 - != (Console->Mode & ENABLE_ECHO_INPUT)) - { - /* echo if it has not already been done, and either we or the client has chars to be deleted */ - if (! Input->Echoed - && (0 != i || Request->Data.ReadConsoleRequest.nCharsCanBeDeleted)) - { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); - } - if (0 != i) - { - i -= 2; /* if we already have something to return, just back it up by 2 */ - } - else - { /* otherwise, return STATUS_NOTIFY_CLEANUP to tell client to back up its buffer */ - Console->WaitingChars--; - ConioUnlockConsole(Console); - HeapFree(Win32CsrApiHeap, 0, Input); - Request->Data.ReadConsoleRequest.NrCharactersRead = 0; - return STATUS_NOTIFY_CLEANUP; - - } - Request->Data.ReadConsoleRequest.nCharsCanBeDeleted--; - Input->Echoed = TRUE; /* mark as echoed so we don't echo it below */ - } - /* do not copy backspace to buffer */ - else - { - if(Request->Data.ReadConsoleRequest.Unicode) - ConsoleInputAnsiCharToUnicodeChar(Console, &UnicodeBuffer[i], &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar); - else - Buffer[i] = Input->InputEvent.Event.KeyEvent.uChar.AsciiChar; - } - /* echo to screen if enabled and we did not already echo the char */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) - && ! Input->Echoed - && '\r' != Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - ConioWriteConsole(Console, Console->ActiveBuffer, - &Input->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE); - } - } - else - { - i--; - } - Console->WaitingChars--; - HeapFree(Win32CsrApiHeap, 0, Input); - } - Request->Data.ReadConsoleRequest.NrCharactersRead = i; - if (0 == i) - { - Status = STATUS_PENDING; /* we didn't read anything */ - } - else if (0 != (Console->Mode & ENABLE_LINE_INPUT)) - { - if (0 == Console->WaitingLines || - (Request->Data.ReadConsoleRequest.Unicode ? (L'\n' != UnicodeBuffer[i - 1]) : ('\n' != Buffer[i - 1]))) - { - Status = STATUS_PENDING; /* line buffered, didn't get a complete line */ - } - else - { - Console->WaitingLines--; - Status = STATUS_SUCCESS; /* line buffered, did get a complete line */ - } - } - else - { - Status = STATUS_SUCCESS; /* not line buffered, did read something */ - } - - if (Status == STATUS_PENDING) - { - Console->EchoCount = nNumberOfCharsToRead - i; - } - else - { - Console->EchoCount = 0; /* if the client is no longer waiting on input, do not echo */ - } - - ConioUnlockConsole(Console); - - if (CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + i * CharSize; - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - } - - return Status; -} - -__inline BOOLEAN ConioGetIntersection( - RECT *Intersection, - RECT *Rect1, - RECT *Rect2) -{ - if (ConioIsRectEmpty(Rect1) || - (ConioIsRectEmpty(Rect2)) || - (Rect1->top > Rect2->bottom) || - (Rect1->left > Rect2->right) || - (Rect1->bottom < Rect2->top) || - (Rect1->right < Rect2->left)) - { - /* The rectangles do not intersect */ - ConioInitRect(Intersection, 0, -1, 0, -1); - return FALSE; - } - - ConioInitRect(Intersection, - max(Rect1->top, Rect2->top), - max(Rect1->left, Rect2->left), - min(Rect1->bottom, Rect2->bottom), - min(Rect1->right, Rect2->right)); - - return TRUE; -} - -__inline BOOLEAN ConioGetUnion( - RECT *Union, - RECT *Rect1, - RECT *Rect2) -{ - if (ConioIsRectEmpty(Rect1)) - { - if (ConioIsRectEmpty(Rect2)) - { - ConioInitRect(Union, 0, -1, 0, -1); - return FALSE; - } - else - { - *Union = *Rect2; - } - } - else if (ConioIsRectEmpty(Rect2)) - { - *Union = *Rect1; - } - else - { - ConioInitRect(Union, - min(Rect1->top, Rect2->top), - min(Rect1->left, Rect2->left), - max(Rect1->bottom, Rect2->bottom), - max(Rect1->right, Rect2->right)); - } - - return TRUE; -} - -/* Move from one rectangle to another. We must be careful about the order that - * this is done, to avoid overwriting parts of the source before they are moved. */ -static VOID FASTCALL -ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, - RECT *SrcRegion, - RECT *DstRegion, - RECT *ClipRegion, - WORD Fill) -{ - int Width = ConioRectWidth(SrcRegion); - int Height = ConioRectHeight(SrcRegion); - int SX, SY; - int DX, DY; - int XDelta, YDelta; - int i, j; - - SY = SrcRegion->top; - DY = DstRegion->top; - YDelta = 1; - if (SY < DY) - { - /* Moving down: work from bottom up */ - SY = SrcRegion->bottom; - DY = DstRegion->bottom; - YDelta = -1; - } - for (i = 0; i < Height; i++) - { - PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); - PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); - - SX = SrcRegion->left; - DX = DstRegion->left; - XDelta = 1; - if (SX < DX) - { - /* Moving right: work from right to left */ - SX = SrcRegion->right; - DX = DstRegion->right; - XDelta = -1; - } - for (j = 0; j < Width; j++) - { - WORD Cell = SRow[SX]; - if (SX >= ClipRegion->left && SX <= ClipRegion->right - && SY >= ClipRegion->top && SY <= ClipRegion->bottom) - { - SRow[SX] = Fill; - } - if (DX >= ClipRegion->left && DX <= ClipRegion->right - && DY >= ClipRegion->top && DY <= ClipRegion->bottom) - { - DRow[DX] = Cell; - } - SX += XDelta; - DX += XDelta; - } - SY += YDelta; - DY += YDelta; - } -} - -static VOID FASTCALL -ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent) -{ - if (InputEvent->EventType == KEY_EVENT) - { - WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; - InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; - ConsoleInputUnicodeCharToAnsiChar(Console, - &InputEvent->Event.KeyEvent.uChar.AsciiChar, - &UnicodeChar); - } -} - -CSR_API(CsrWriteConsole) -{ - NTSTATUS Status; - PCHAR Buffer; - PCSRSS_SCREEN_BUFFER Buff; - PCSRSS_CONSOLE Console; - DWORD Written = 0; - ULONG Length; - ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - DPRINT("CsrWriteConsole\n"); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) - + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize)) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - Status = ConioConsoleFromProcessData(ProcessData, &Console); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (! NT_SUCCESS(Status)) - { - return Status; - } - - if(Request->Data.WriteConsoleRequest.Unicode) - { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, - NULL, 0, NULL, NULL); - Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length); - if (Buffer) - { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, - Buffer, Length, NULL, NULL); - } - else - { - Status = STATUS_NO_MEMORY; - } - } - else - { - Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer; - } - - if (Buffer) - { - Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (NT_SUCCESS(Status)) - { - Status = ConioWriteConsole(Console, Buff, Buffer, - Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE); - if (NT_SUCCESS(Status)) - { - Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; - } - ConioUnlockScreenBuffer(Buff); - } - if (Request->Data.WriteConsoleRequest.Unicode) - { - RtlFreeHeap(GetProcessHeap(), 0, Buffer); - } - } - ConioUnlockConsole(Console); - - Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; - - return Status; -} - -VOID WINAPI -ConioDeleteScreenBuffer(Object_t *Object) -{ - PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object; - DeleteCriticalSection(&Buffer->Header.Lock); - HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); - HeapFree(Win32CsrApiHeap, 0, Buffer); -} - -VOID FASTCALL -ConioDrawConsole(PCSRSS_CONSOLE Console) -{ - RECT Region; - - ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); - - ConioDrawRegion(Console, &Region); -} - - -VOID WINAPI -ConioDeleteConsole(Object_t *Object) -{ - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object; - ConsoleInput *Event; - - DPRINT("ConioDeleteConsole\n"); - - /* Drain input event queue */ - while (Console->InputEvents.Flink != &Console->InputEvents) - { - Event = (ConsoleInput *) Console->InputEvents.Flink; - Console->InputEvents.Flink = Console->InputEvents.Flink->Flink; - Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents; - HeapFree(Win32CsrApiHeap, 0, Event); - } - - ConioCleanupConsole(Console); - if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount)) - { - ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); - } - - Console->ActiveBuffer = NULL; - - CloseHandle(Console->ActiveEvent); - DeleteCriticalSection(&Console->Header.Lock); - RtlFreeUnicodeString(&Console->Title); - IntDeleteAllAliases(Console->Aliases); - HeapFree(Win32CsrApiHeap, 0, Console); -} - -VOID WINAPI -CsrInitConsoleSupport(VOID) -{ - DPRINT("CSR: CsrInitConsoleSupport()\n"); - - /* Should call LoadKeyboardLayout */ -} - -static VOID FASTCALL -ConioProcessChar(PCSRSS_CONSOLE Console, - ConsoleInput *KeyEventRecord) -{ - BOOL updown; - ConsoleInput *TempInput; - - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT))) - { - switch(KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - case '\r': - /* first add the \r */ - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown; - KeyEventRecord->Echoed = FALSE; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r'; - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - KeyEventRecord = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == KeyEventRecord) - { - DPRINT1("Failed to allocate KeyEventRecord\n"); - return; - } - KeyEventRecord->InputEvent.EventType = KEY_EVENT; - KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown = updown; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualScanCode = 0; - KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n'; - KeyEventRecord->Fake = TRUE; - break; - } - } - /* add event to the queue */ - InsertTailList(&Console->InputEvents, &KeyEventRecord->ListEntry); - Console->WaitingChars++; - /* if line input mode is enabled, only wake the client on enter key down */ - if (0 == (Console->Mode & ENABLE_LINE_INPUT) - || Console->EarlyReturn - || ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown)) - { - if ('\n' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - Console->WaitingLines++; - } - } - KeyEventRecord->Echoed = FALSE; - if (0 != (Console->Mode & (ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT)) - && '\b' == KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown) - { - /* walk the input queue looking for a char to backspace */ - for (TempInput = (ConsoleInput *) Console->InputEvents.Blink; - TempInput != (ConsoleInput *) &Console->InputEvents - && (KEY_EVENT == TempInput->InputEvent.EventType - || ! TempInput->InputEvent.Event.KeyEvent.bKeyDown - || '\b' == TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar); - TempInput = (ConsoleInput *) TempInput->ListEntry.Blink) - { - /* NOP */; - } - /* if we found one, delete it, otherwise, wake the client */ - if (TempInput != (ConsoleInput *) &Console->InputEvents) - { - /* delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue */ - RemoveEntryList(&TempInput->ListEntry); - if (TempInput->Echoed) - { - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); - } - HeapFree(Win32CsrApiHeap, 0, TempInput); - RemoveEntryList(&KeyEventRecord->ListEntry); - HeapFree(Win32CsrApiHeap, 0, KeyEventRecord); - Console->WaitingChars -= 2; - return; - } - } - else - { - /* echo chars if we are supposed to and client is waiting for some */ - if (0 != (Console->Mode & ENABLE_ECHO_INPUT) && Console->EchoCount - && KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar - && KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown - && '\r' != KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - /* mark the char as already echoed */ - ConioWriteConsole(Console, Console->ActiveBuffer, - &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, - 1, TRUE); - Console->EchoCount--; - KeyEventRecord->Echoed = TRUE; - } - } - - /* Console->WaitingChars++; */ - SetEvent(Console->ActiveEvent); -} - -static DWORD FASTCALL -ConioGetShiftState(PBYTE KeyState) -{ - DWORD ssOut = 0; - - if (KeyState[VK_CAPITAL] & 1) - ssOut |= CAPSLOCK_ON; - - if (KeyState[VK_NUMLOCK] & 1) - ssOut |= NUMLOCK_ON; - - if (KeyState[VK_SCROLL] & 1) - ssOut |= SCROLLLOCK_ON; - - if (KeyState[VK_SHIFT] & 0x80) - ssOut |= SHIFT_PRESSED; - - if (KeyState[VK_LCONTROL] & 0x80) - ssOut |= LEFT_CTRL_PRESSED; - if (KeyState[VK_RCONTROL] & 0x80) - ssOut |= RIGHT_CTRL_PRESSED; - - if (KeyState[VK_LMENU] & 0x80) - ssOut |= LEFT_ALT_PRESSED; - if (KeyState[VK_RMENU] & 0x80) - ssOut |= RIGHT_ALT_PRESSED; - - return ssOut; -} - -VOID WINAPI -ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) -{ - static BYTE KeyState[256] = { 0 }; - /* MSDN mentions that you should use the last virtual key code received - * when putting a virtual key identity to a WM_CHAR message since multiple - * or translated keys may be involved. */ - static UINT LastVirtualKey = 0; - DWORD ShiftState; - ConsoleInput *ConInRec; - UINT RepeatCount; - CHAR AsciiChar; - WCHAR UnicodeChar; - UINT VirtualKeyCode; - UINT VirtualScanCode; - BOOL Down = FALSE; - INPUT_RECORD er; - ULONG ResultSize = 0; - - RepeatCount = 1; - VirtualScanCode = (msg->lParam >> 16) & 0xff; - Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || - msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; - - GetKeyboardState(KeyState); - ShiftState = ConioGetShiftState(KeyState); - - if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) - { - VirtualKeyCode = LastVirtualKey; - UnicodeChar = msg->wParam; - } - else - { - WCHAR Chars[2]; - INT RetChars = 0; - - VirtualKeyCode = msg->wParam; - RetChars = ToUnicodeEx(VirtualKeyCode, - VirtualScanCode, - KeyState, - Chars, - 2, - 0, - 0); - UnicodeChar = (1 == RetChars ? Chars[0] : 0); - } - - if (0 == ResultSize) - { - AsciiChar = 0; - } - - er.EventType = KEY_EVENT; - er.Event.KeyEvent.bKeyDown = Down; - er.Event.KeyEvent.wRepeatCount = RepeatCount; - er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; - er.Event.KeyEvent.dwControlKeyState = ShiftState; - er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; - er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; - - if (TextMode) - { - if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && VK_TAB == VirtualKeyCode) - { - if (Down) - { - TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); - } - - return; - } - else if (VK_MENU == VirtualKeyCode && ! Down) - { - if (TuiSwapConsole(0)) - { - return; - } - } - } - - if (NULL == Console) - { - DPRINT1("No Active Console!\n"); - return; - } - - ConInRec = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - - if (NULL == ConInRec) - { - return; - } - - ConInRec->InputEvent = er; - ConInRec->Fake = UnicodeChar && - (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && - msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); - ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - ConInRec->Echoed = FALSE; - if (ConInRec->NotChar) - LastVirtualKey = msg->wParam; - - DPRINT ("csrss: %s %s %s %s %02x %02x '%c' %04x\n", - Down ? "down" : "up ", - (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? - "char" : "key ", - ConInRec->Fake ? "fake" : "real", - ConInRec->NotChar ? "notc" : "char", - VirtualScanCode, - VirtualKeyCode, - (AsciiChar >= ' ') ? AsciiChar : '.', - ShiftState); - - if (ConInRec->Fake && ConInRec->NotChar) - { - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - - /* process Ctrl-C and Ctrl-Break */ - if (Console->Mode & ENABLE_PROCESSED_INPUT && - er.Event.KeyEvent.bKeyDown && - ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || - (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && - (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))) - { - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - DPRINT1("Console_Api Ctrl-C\n"); - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - current_entry = current_entry->Flink; - ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current); - } - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - - if (0 != (er.Event.KeyEvent.dwControlKeyState - & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode - || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) - { - if (er.Event.KeyEvent.bKeyDown) - { - /* scroll up or down */ - if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) - { - /* only scroll up if there is room to scroll up into */ - if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + - Console->ActiveBuffer->MaxY - 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY++; - } - } - else - { - /* only scroll down if there is room to scroll down into */ - if (Console->ActiveBuffer->CurrentY != 0) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % - Console->ActiveBuffer->MaxY; - Console->ActiveBuffer->CurrentY--; - } - } - ConioDrawConsole(Console); - } - HeapFree(Win32CsrApiHeap, 0, ConInRec); - return; - } - /* FIXME - convert to ascii */ - ConioProcessChar(Console, ConInRec); -} - -CSR_API(CsrGetScreenBufferInfo) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PCONSOLE_SCREEN_BUFFER_INFO pInfo; - - DPRINT("CsrGetScreenBufferInfo\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - pInfo = &Request->Data.ScreenBufferInfoRequest.Info; - pInfo->dwSize.X = Buff->MaxX; - pInfo->dwSize.Y = Buff->MaxY; - pInfo->dwCursorPosition.X = Buff->CurrentX; - pInfo->dwCursorPosition.Y = Buff->CurrentY; - pInfo->wAttributes = Buff->DefaultAttrib; - pInfo->srWindow.Left = Buff->ShowX; - pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; - pInfo->srWindow.Top = Buff->ShowY; - pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; - pInfo->dwMaximumWindowSize.X = Buff->MaxX; - pInfo->dwMaximumWindowSize.Y = Buff->MaxY; - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetCursor) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - LONG OldCursorX, OldCursorY; - LONG NewCursorX, NewCursorY; - - DPRINT("CsrSetCursor\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - NewCursorX = Request->Data.SetCursorRequest.Position.X; - NewCursorY = Request->Data.SetCursorRequest.Position.Y; - if (NewCursorX < 0 || NewCursorX >= Buff->MaxX || - NewCursorY < 0 || NewCursorY >= Buff->MaxY) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; - } - OldCursorX = Buff->CurrentX; - OldCursorY = Buff->CurrentY; - Buff->CurrentX = NewCursorX; - Buff->CurrentY = NewCursorY; - if (Buff == Console->ActiveBuffer) - { - if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_UNSUCCESSFUL; - } - } - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -static VOID FASTCALL -ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, RECT *UpdateRect, COORD *Start, UINT Length) -{ - if (Buff->MaxX <= Start->X + Length) - { - UpdateRect->left = 0; - } - else - { - UpdateRect->left = Start->X; - } - if (Buff->MaxX <= Start->X + Length) - { - UpdateRect->right = Buff->MaxX - 1; - } - else - { - UpdateRect->right = Start->X + Length - 1; - } - UpdateRect->top = Start->Y; - UpdateRect->bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; - if (Buff->MaxY <= UpdateRect->bottom) - { - UpdateRect->bottom = Buff->MaxY - 1; - } -} - -CSR_API(CsrWriteConsoleOutputChar) -{ - NTSTATUS Status; - PCHAR String, tmpString = NULL; - PBYTE Buffer; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, CharSize, Written = 0; - RECT UpdateRect; - - DPRINT("CsrWriteConsoleOutputChar\n"); - - CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) - + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize)) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (NT_SUCCESS(Status)) - { - if(Request->Data.WriteConsoleOutputCharRequest.Unicode) - { - Length = WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, - Request->Data.WriteConsoleOutputCharRequest.Length, - NULL, 0, NULL, NULL); - tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); - if (String) - { - WideCharToMultiByte(Console->OutputCodePage, 0, - (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, - Request->Data.WriteConsoleOutputCharRequest.Length, - String, Length, NULL, NULL); - } - else - { - Status = STATUS_NO_MEMORY; - } - } - else - { - String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String; - } - - if (String) - { - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (NT_SUCCESS(Status)) - { - X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; - Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.WriteConsoleOutputCharRequest.Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - while (Length--) - { - *Buffer = *String++; - Written++; - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer; - } - X = 0; - } - } - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord, - Request->Data.WriteConsoleOutputCharRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X; - Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - } - if (Request->Data.WriteConsoleRequest.Unicode) - { - RtlFreeHeap(GetProcessHeap(), 0, tmpString); - } - } - ConioUnlockConsole(Console); - } - Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; - return Status; -} - -CSR_API(CsrFillOutputChar) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, Length, Written = 0; - CHAR Char; - PBYTE Buffer; - RECT UpdateRect; - - DPRINT("CsrFillOutputChar\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - X = Request->Data.FillOutputRequest.Position.X; - Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; - if(Request->Data.FillOutputRequest.Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar); - else - Char = Request->Data.FillOutputRequest.Char.AsciiChar; - Length = Request->Data.FillOutputRequest.Length; - while (Length--) - { - *Buffer = Char; - Buffer += 2; - Written++; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer; - } - X = 0; - } - } - - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position, - Request->Data.FillOutputRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - Length = Request->Data.FillOutputRequest.Length; - Request->Data.FillOutputRequest.NrCharactersWritten = Length; - return STATUS_SUCCESS; -} - -CSR_API(CsrReadInputEvent) -{ - PLIST_ENTRY CurrentEntry; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - BOOLEAN Done = FALSE; - ConsoleInput *Input; - - DPRINT("CsrReadInputEvent\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent; - - Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - /* only get input if there is any */ - CurrentEntry = Console->InputEvents.Flink; - while (CurrentEntry != &Console->InputEvents) - { - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - CurrentEntry = CurrentEntry->Flink; - - if (Done && !Input->Fake) - { - Request->Data.ReadInputRequest.MoreEvents = TRUE; - break; - } - - RemoveEntryList(&Input->ListEntry); - - if (!Done && !Input->Fake) - { - Request->Data.ReadInputRequest.Input = Input->InputEvent; - if (Request->Data.ReadInputRequest.Unicode == FALSE) - { - ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input); - } - Done = TRUE; - } - - if (Input->InputEvent.EventType == KEY_EVENT) - { - if (0 != (Console->Mode & ENABLE_LINE_INPUT) - && Input->InputEvent.Event.KeyEvent.bKeyDown - && '\r' == Input->InputEvent.Event.KeyEvent.uChar.AsciiChar) - { - Console->WaitingLines--; - } - Console->WaitingChars--; - } - HeapFree(Win32CsrApiHeap, 0, Input); - } - - if (Done) - { - Status = STATUS_SUCCESS; - Console->EarlyReturn = FALSE; - } - else - { - Status = STATUS_PENDING; - Console->EarlyReturn = TRUE; /* mark for early return */ - } - - if (IsListEmpty(&Console->InputEvents)) - { - ResetEvent(Console->ActiveEvent); - } - - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrWriteConsoleOutputAttrib) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - PWORD Attribute; - int X, Y, Length; - NTSTATUS Status; - RECT UpdateRect; - - DPRINT("CsrWriteConsoleOutputAttrib\n"); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) - + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD)) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; - Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.WriteConsoleOutputAttribRequest.Length; - Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; - Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute; - while (Length--) - { - *Buffer = (UCHAR)(*Attribute++); - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer + 1; - } - X = 0; - } - } - - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord, - Request->Data.WriteConsoleOutputAttribRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - ConioUnlockConsole(Console); - - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; - Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrFillOutputAttrib) -{ - PCSRSS_SCREEN_BUFFER Buff; - PUCHAR Buffer; - NTSTATUS Status; - int X, Y, Length; - UCHAR Attr; - RECT UpdateRect; - PCSRSS_CONSOLE Console; - - DPRINT("CsrFillOutputAttrib\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - X = Request->Data.FillOutputAttribRequest.Coord.X; - Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; - Length = Request->Data.FillOutputAttribRequest.Length; - Attr = Request->Data.FillOutputAttribRequest.Attribute; - Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; - while (Length--) - { - *Buffer = Attr; - Buffer += 2; - if (++X == Buff->MaxX) - { - if (++Y == Buff->MaxY) - { - Y = 0; - Buffer = Buff->Buffer + 1; - } - X = 0; - } - } - - if (Buff == Console->ActiveBuffer) - { - ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord, - Request->Data.FillOutputAttribRequest.Length); - ConioDrawRegion(Console, &UpdateRect); - } - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - - -CSR_API(CsrGetCursorInfo) -{ - PCSRSS_SCREEN_BUFFER Buff; - NTSTATUS Status; - - DPRINT("CsrGetCursorInfo\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; - Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; - ConioUnlockScreenBuffer(Buff); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetCursorInfo) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - BOOL Visible; - NTSTATUS Status; - - DPRINT("CsrSetCursorInfo\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - Size = Request->Data.SetCursorInfoRequest.Info.dwSize; - Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; - if (Size < 1) - { - Size = 1; - } - if (100 < Size) - { - Size = 100; - } - - if (Size != Buff->CursorInfo.dwSize - || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible)) - { - Buff->CursorInfo.dwSize = Size; - Buff->CursorInfo.bVisible = Visible; - - if (! ConioSetCursorInfo(Console, Buff)) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_UNSUCCESSFUL; - } - } - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetTextAttrib) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - DPRINT("CsrSetTextAttrib\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; - if (Buff == Console->ActiveBuffer) - { - if (! ConioUpdateScreenInfo(Console, Buff)) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_UNSUCCESSFUL; - } - } - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleMode) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - DPRINT("CsrSetConsoleMode\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrGetObject(ProcessData, - Request->Data.SetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Buff = (PCSRSS_SCREEN_BUFFER)Console; - if (CONIO_CONSOLE_MAGIC == Console->Header.Type) - { - Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID; - } - else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type) - { - Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID; - } - else - { - Status = STATUS_INVALID_HANDLE; - } - - Win32CsrReleaseObjectByPointer((Object_t *)Console); - - return Status; -} - -CSR_API(CsrGetConsoleMode) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */ - - DPRINT("CsrGetConsoleMode\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = Win32CsrGetObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, - (Object_t **) &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - Status = STATUS_SUCCESS; - Buff = (PCSRSS_SCREEN_BUFFER) Console; - if (CONIO_CONSOLE_MAGIC == Console->Header.Type) - { - Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode; - } - else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type) - { - Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode; - } - else - { - Status = STATUS_INVALID_HANDLE; - } - - Win32CsrReleaseObjectByPointer((Object_t *)Console); - return Status; -} - -CSR_API(CsrCreateScreenBuffer) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - NTSTATUS Status; - - DPRINT("CsrCreateScreenBuffer\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); - - if (Buff != NULL) - { - if (Console->ActiveBuffer) - { - Buff->MaxX = Console->ActiveBuffer->MaxX; - Buff->MaxY = Console->ActiveBuffer->MaxY; - Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; - Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; - } - else - { - Buff->CursorInfo.bVisible = TRUE; - Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; - } - - if (Buff->MaxX == 0) - { - Buff->MaxX = 80; - } - - if (Buff->MaxY == 0) - { - Buff->MaxY = 25; - } - - Status = CsrInitConsoleScreenBuffer(Console, Buff); - if(NT_SUCCESS(Status)) - { - Status = Win32CsrInsertObject(ProcessData, - &Request->Data.CreateScreenBufferRequest.OutputHandle, - &Buff->Header, - Request->Data.CreateScreenBufferRequest.Access, - Request->Data.CreateScreenBufferRequest.Inheritable); - } - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - - ConioUnlockConsole(Console); - return Status; -} - -CSR_API(CsrSetScreenBuffer) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - DPRINT("CsrSetScreenBuffer\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - if (Buff == Console->ActiveBuffer) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_SUCCESS; - } - - /* drop reference to old buffer, maybe delete */ - if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount)) - { - ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); - } - /* tie console to new buffer */ - Console->ActiveBuffer = Buff; - /* inc ref count on new buffer */ - InterlockedIncrement(&Buff->Header.ReferenceCount); - /* Redraw the console */ - ConioDrawConsole(Console); - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetTitle) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PWCHAR Buffer; - - DPRINT("CsrSetTitle\n"); - - if (Request->Header.u1.s1.TotalLength - < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) - + Request->Data.SetTitleRequest.Length) - { - DPRINT1("Invalid request size\n"); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - return STATUS_INVALID_PARAMETER; - } - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if(NT_SUCCESS(Status)) - { - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); - if (Buffer) - { - /* copy title to console */ - RtlFreeUnicodeString(&Console->Title); - Console->Title.Buffer = Buffer; - Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length; - memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length); - if (! ConioChangeTitle(Console)) - { - Status = STATUS_UNSUCCESSFUL; - } - else - { - Status = STATUS_SUCCESS; - } - } - else - { - Status = STATUS_NO_MEMORY; - } - ConioUnlockConsole(Console); - } - - return Status; -} - -CSR_API(CsrGetTitle) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - DWORD Length; - - DPRINT("CsrGetTitle\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Can't get console\n"); - return Status; - } - - /* Copy title of the console to the user title buffer */ - RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); - Request->Data.GetTitleRequest.Length = Console->Title.Length; - memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, - Console->Title.Length); - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + Console->Title.Length; - - ConioUnlockConsole(Console); - - if (Length > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); - } - return STATUS_SUCCESS; -} - -CSR_API(CsrWriteConsoleOutput) -{ - SHORT i, X, Y, SizeX, SizeY; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - RECT ScreenBuffer; - CHAR_INFO* CurCharInfo; - RECT WriteRegion; - CHAR_INFO* CharInfo; - COORD BufferCoord; - COORD BufferSize; - NTSTATUS Status; - PBYTE Ptr; - DWORD PSize; - - DPRINT("CsrWriteConsoleOutput\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, - Request->Data.WriteConsoleOutputRequest.ConsoleHandle, - &Buff, - GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; - PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO); - BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; - CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) || - (((ULONG_PTR)CharInfo + PSize) > - ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; - } - WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left; - WriteRegion.top = Request->Data.WriteConsoleOutputRequest.WriteRegion.Top; - WriteRegion.right = Request->Data.WriteConsoleOutputRequest.WriteRegion.Right; - WriteRegion.bottom = Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom; - - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); - WriteRegion.bottom = WriteRegion.top + SizeY - 1; - WriteRegion.right = WriteRegion.left + SizeX - 1; - - /* Make sure WriteRegion is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); - if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - /* It is okay to have a WriteRegion completely outside the screen buffer. - No data is written then. */ - return STATUS_SUCCESS; - } - - for (i = 0, Y = WriteRegion.top; Y <= WriteRegion.bottom; i++, Y++) - { - CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; - Ptr = ConioCoordToPointer(Buff, WriteRegion.left, Y); - for (X = WriteRegion.left; X <= WriteRegion.right; X++) - { - CHAR AsciiChar; - if (Request->Data.WriteConsoleOutputRequest.Unicode) - { - ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); - } - else - { - AsciiChar = CurCharInfo->Char.AsciiChar; - } - *Ptr++ = AsciiChar; - *Ptr++ = CurCharInfo->Attributes; - CurCharInfo++; - } - } - - ConioDrawRegion(Console, &WriteRegion); - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY - 1; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.left; - Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.top; - - return STATUS_SUCCESS; -} - -CSR_API(CsrFlushInputBuffer) -{ - PLIST_ENTRY CurrentEntry; - PCSRSS_CONSOLE Console; - ConsoleInput* Input; - NTSTATUS Status; - - DPRINT("CsrFlushInputBuffer\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockConsole(ProcessData, - Request->Data.FlushInputBufferRequest.ConsoleInput, - &Console, - GENERIC_WRITE); - if(! NT_SUCCESS(Status)) - { - return Status; - } - - /* Discard all entries in the input event queue */ - while (!IsListEmpty(&Console->InputEvents)) - { - CurrentEntry = RemoveHeadList(&Console->InputEvents); - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - /* Destroy the event */ - HeapFree(Win32CsrApiHeap, 0, Input); - } - ResetEvent(Console->ActiveEvent); - Console->WaitingChars=0; - - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrScrollConsoleScreenBuffer) -{ - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - RECT ScreenBuffer; - RECT SrcRegion; - RECT DstRegion; - RECT UpdateRegion; - RECT ScrollRectangle; - RECT ClipRectangle; - NTSTATUS Status; - HANDLE ConsoleHandle; - BOOLEAN UseClipRectangle; - COORD DestinationOrigin; - CHAR_INFO Fill; - CHAR FillChar; - - DPRINT("CsrScrollConsoleScreenBuffer\n"); - - ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle; - UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle; - DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; - Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - ScrollRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left; - ScrollRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top; - ScrollRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Right; - ScrollRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Bottom; - - /* Make sure source rectangle is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); - if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) - { - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - return STATUS_SUCCESS; - } - - /* If the source was clipped on the left or top, adjust the destination accordingly */ - if (ScrollRectangle.left < 0) - { - DestinationOrigin.X -= ScrollRectangle.left; - } - if (ScrollRectangle.top < 0) - { - DestinationOrigin.Y -= ScrollRectangle.top; - } - - if (UseClipRectangle) - { - ClipRectangle.left = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Left; - ClipRectangle.top = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Top; - ClipRectangle.right = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Right; - ClipRectangle.bottom = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom; - if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) - { - ConioUnlockConsole(Console); - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } - } - else - { - ClipRectangle = ScreenBuffer; - } - - ConioInitRect(&DstRegion, - DestinationOrigin.Y, - DestinationOrigin.X, - DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, - DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); - - if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode) - ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); - else - FillChar = Fill.Char.AsciiChar; - - ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); - - if (Buff == Console->ActiveBuffer) - { - ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); - if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) - { - /* Draw update region */ - ConioDrawRegion(Console, &UpdateRegion); - } - } - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrReadConsoleOutputChar) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Xpos, Ypos; - PCHAR ReadBuffer; - DWORD i; - ULONG CharSize; - CHAR Char; - - DPRINT("CsrReadConsoleOutputChar\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String; - - CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; - Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; - - for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) - { - Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)]; - - if(Request->Data.ReadConsoleOutputCharRequest.Unicode) - { - ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char); - ReadBuffer += sizeof(WCHAR); - } - else - *(ReadBuffer++) = Char; - - Xpos++; - - if (Xpos == Buff->MaxX) - { - Xpos = 0; - Ypos++; - - if (Ypos == Buff->MaxY) - { - Ypos = 0; - } - } - } - - *ReadBuffer = 0; - Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos; - Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; - if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - } - - return STATUS_SUCCESS; -} - - -CSR_API(CsrReadConsoleOutputAttrib) -{ - NTSTATUS Status; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Xpos, Ypos; - PWORD ReadBuffer; - DWORD i; - DWORD CurrentLength; - - DPRINT("CsrReadConsoleOutputAttrib\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute; - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X; - Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; - - for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) - { - *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1]; - - ReadBuffer++; - Xpos++; - - if (Xpos == Buff->MaxX) - { - Xpos = 0; - Ypos++; - - if (Ypos == Buff->MaxY) - { - Ypos = 0; - } - } - } - - *ReadBuffer = 0; - - Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos; - Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; - - ConioUnlockScreenBuffer(Buff); - - CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) - + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD); - if (CurrentLength > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = CurrentLength; - Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE); - } - - return STATUS_SUCCESS; -} - - -CSR_API(CsrGetNumberOfConsoleInputEvents) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PLIST_ENTRY CurrentItem; - DWORD NumEvents; - ConsoleInput *Input; - - DPRINT("CsrGetNumberOfConsoleInputEvents\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - CurrentItem = Console->InputEvents.Flink; - NumEvents = 0; - - /* If there are any events ... */ - while (CurrentItem != &Console->InputEvents) - { - Input = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - CurrentItem = CurrentItem->Flink; - if (!Input->Fake) - { - NumEvents++; - } - } - - ConioUnlockConsole(Console); - - Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents; - - return STATUS_SUCCESS; -} - - -CSR_API(CsrPeekConsoleInput) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - DWORD Size; - DWORD Length; - PLIST_ENTRY CurrentItem; - PINPUT_RECORD InputRecord; - ConsoleInput* Item; - UINT NumItems; - - DPRINT("CsrPeekConsoleInput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ); - if(! NT_SUCCESS(Status)) - { - return Status; - } - - InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord; - Length = Request->Data.PeekConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; - } - - NumItems = 0; - - if (! IsListEmpty(&Console->InputEvents)) - { - CurrentItem = Console->InputEvents.Flink; - - while (CurrentItem != &Console->InputEvents && NumItems < Length) - { - Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry); - - if (Item->Fake) - { - CurrentItem = CurrentItem->Flink; - continue; - } - - ++NumItems; - *InputRecord = Item->InputEvent; - - if (Request->Data.ReadInputRequest.Unicode == FALSE) - { - ConioInputEventToAnsi(Console, InputRecord); - } - - InputRecord++; - CurrentItem = CurrentItem->Flink; - } - } - - ConioUnlockConsole(Console); - - Request->Data.PeekConsoleInputRequest.Length = NumItems; - - return STATUS_SUCCESS; -} - - -CSR_API(CsrReadConsoleOutput) -{ - PCHAR_INFO CharInfo; - PCHAR_INFO CurCharInfo; - PCSRSS_SCREEN_BUFFER Buff; - DWORD Size; - DWORD Length; - DWORD SizeX, SizeY; - NTSTATUS Status; - COORD BufferSize; - COORD BufferCoord; - RECT ReadRegion; - RECT ScreenRect; - DWORD i; - PBYTE Ptr; - LONG X, Y; - UINT CodePage; - - DPRINT("CsrReadConsoleOutput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; - ReadRegion.left = Request->Data.ReadConsoleOutputRequest.ReadRegion.Left; - ReadRegion.top = Request->Data.ReadConsoleOutputRequest.ReadRegion.Top; - ReadRegion.right = Request->Data.ReadConsoleOutputRequest.ReadRegion.Right; - ReadRegion.bottom = Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom; - BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; - BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; - Length = BufferSize.X * BufferSize.Y; - Size = Length * sizeof(CHAR_INFO); - - /* FIXME: Is this correct? */ - CodePage = ProcessData->Console->OutputCodePage; - - if (((PVOID)CharInfo < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)CharInfo + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_ACCESS_VIOLATION; - } - - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); - ReadRegion.bottom = ReadRegion.top + SizeY; - ReadRegion.right = ReadRegion.left + SizeX; - - ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); - if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) - { - ConioUnlockScreenBuffer(Buff); - return STATUS_SUCCESS; - } - - for (i = 0, Y = ReadRegion.top; Y < ReadRegion.bottom; ++i, ++Y) - { - CurCharInfo = CharInfo + (i * BufferSize.X); - - Ptr = ConioCoordToPointer(Buff, ReadRegion.left, Y); - for (X = ReadRegion.left; X < ReadRegion.right; ++X) - { - if (Request->Data.ReadConsoleOutputRequest.Unicode) - { - MultiByteToWideChar(CodePage, 0, - (PCHAR)Ptr++, 1, - &CurCharInfo->Char.UnicodeChar, 1); - } - else - { - CurCharInfo->Char.AsciiChar = *Ptr++; - } - CurCharInfo->Attributes = *Ptr++; - ++CurCharInfo; - } - } - - ConioUnlockScreenBuffer(Buff); - - Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.left + SizeX - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.top + SizeY - 1; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.left; - Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.top; - - return STATUS_SUCCESS; -} - - -CSR_API(CsrWriteConsoleInput) -{ - PINPUT_RECORD InputRecord; - PCSRSS_CONSOLE Console; - NTSTATUS Status; - DWORD Length; - DWORD Size; - DWORD i; - ConsoleInput* Record; - - DPRINT("CsrWriteConsoleInput\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord; - Length = Request->Data.WriteConsoleInputRequest.Length; - Size = Length * sizeof(INPUT_RECORD); - - if (((PVOID)InputRecord < ProcessData->CsrSectionViewBase) - || (((ULONG_PTR)InputRecord + Size) > ((ULONG_PTR)ProcessData->CsrSectionViewBase + ProcessData->CsrSectionViewSize))) - { - ConioUnlockConsole(Console); - return STATUS_ACCESS_VIOLATION; - } - - for (i = 0; i < Length; i++) - { - Record = HeapAlloc(Win32CsrApiHeap, 0, sizeof(ConsoleInput)); - if (NULL == Record) - { - ConioUnlockConsole(Console); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Record->Echoed = FALSE; - Record->Fake = FALSE; - //Record->InputEvent = *InputRecord++; - memcpy(&Record->InputEvent, &InputRecord[i], sizeof(INPUT_RECORD)); - if (KEY_EVENT == Record->InputEvent.EventType) - { - /* FIXME - convert from unicode to ascii!! */ - ConioProcessChar(Console, Record); - } - } - - ConioUnlockConsole(Console); - - Request->Data.WriteConsoleInputRequest.Length = i; - - return STATUS_SUCCESS; -} - -/********************************************************************** - * HardwareStateProperty - * - * DESCRIPTION - * Set/Get the value of the HardwareState and switch - * between direct video buffer ouput and GDI windowed - * output. - * ARGUMENTS - * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE - * object. We use the same object to Request. - * NOTE - * ConsoleHwState has the correct size to be compatible - * with NT's, but values are not. - */ -static NTSTATUS FASTCALL -SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState) -{ - DPRINT1("Console Hardware State: %d\n", ConsoleHwState); - - if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) - ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) - { - if (Console->HardwareState != ConsoleHwState) - { - /* TODO: implement switching from full screen to windowed mode */ - /* TODO: or back; now simply store the hardware state */ - Console->HardwareState = ConsoleHwState; - } - - return STATUS_SUCCESS; - } - - return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ -} - -CSR_API(CsrHardwareStateProperty) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrHardwareStateProperty\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioLockConsole(ProcessData, - Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, - &Console, - GENERIC_READ); - if (! NT_SUCCESS(Status)) - { - DPRINT1("Failed to get console handle in SetConsoleHardwareState\n"); - return Status; - } - - switch (Request->Data.ConsoleHardwareStateRequest.SetGet) - { - case CONSOLE_HARDWARE_STATE_GET: - Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState; - break; - - case CONSOLE_HARDWARE_STATE_SET: - DPRINT("Setting console hardware state.\n"); - Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State); - break; - - default: - Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */ - break; - } - - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrGetConsoleWindow) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrGetConsoleWindow\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow; - ConioUnlockConsole(Console); - - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleIcon) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrSetConsoleIcon\n"); - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon) - ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrGetConsoleCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrGetConsoleCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.GetConsoleCodePage.CodePage = Console->CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrSetConsoleCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage)) - { - Console->CodePage = Request->Data.SetConsoleCodePage.CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; - } - - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; -} - -CSR_API(CsrGetConsoleOutputCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrGetConsoleOutputCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; -} - -CSR_API(CsrSetConsoleOutputCodePage) -{ - PCSRSS_CONSOLE Console; - NTSTATUS Status; - - DPRINT("CsrSetConsoleOutputCodePage\n"); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage)) - { - Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage; - ConioUnlockConsole(Console); - return STATUS_SUCCESS; - } - - ConioUnlockConsole(Console); - return STATUS_INVALID_PARAMETER; -} - -CSR_API(CsrGetProcessList) -{ - PHANDLE Buffer; - PCSRSS_CONSOLE Console; - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - ULONG nItems, nCopied, Length; - NTSTATUS Status; - - DPRINT("CsrGetProcessList\n"); - - Buffer = Request->Data.GetProcessListRequest.ProcessId; - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - nItems = nCopied = 0; - Request->Data.GetProcessListRequest.nProcessIdsCopied = 0; - Request->Data.GetProcessListRequest.nProcessIdsTotal = 0; - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - DPRINT1("Console_Api Ctrl-C\n"); - - for(current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if(++nItems < Request->Data.GetProcessListRequest.nMaxIds) - { - *(Buffer++) = current->ProcessId; - nCopied++; - } - } - - ConioUnlockConsole(Console); - - Request->Data.GetProcessListRequest.nProcessIdsCopied = nCopied; - Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; - - Length = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST) + nCopied * sizeof(HANDLE); - if (Length > sizeof(CSR_API_MESSAGE)) - { - Request->Header.u1.s1.TotalLength = Length; - Request->Header.u1.s1.DataLength = Length - sizeof(PORT_MESSAGE); - } - return STATUS_SUCCESS; -} - -CSR_API(CsrGenerateCtrlEvent) -{ - PCSRSS_CONSOLE Console; - PCSRSS_PROCESS_DATA current; - PLIST_ENTRY current_entry; - DWORD Group; - NTSTATUS Status; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (! NT_SUCCESS(Status)) - { - return Status; - } - - Group = Request->Data.GenerateCtrlEvent.ProcessGroup; - Status = STATUS_INVALID_PARAMETER; - for (current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - if (Group == 0 || current->ProcessGroup == Group) - { - ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current); - Status = STATUS_SUCCESS; - } - } - - ConioUnlockConsole(Console); - - return Status; -} - -CSR_API(CsrSetScreenBufferSize) -{ - NTSTATUS Status; - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - - Status = ConioConsoleFromProcessData(ProcessData, &Console); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE); - if (!NT_SUCCESS(Status)) - { - ConioUnlockConsole(Console); - return Status; - } - - Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size); - ConioUnlockScreenBuffer(Buff); - ConioUnlockConsole(Console); - - return Status; -} - -/* EOF */ diff --git a/subsystems/win32/csrss/include/conio.h b/subsystems/win32/csrss/win32csr/conio.h similarity index 72% rename from subsystems/win32/csrss/include/conio.h rename to subsystems/win32/csrss/win32csr/conio.h index cf62ac71c52..bd66928bddd 100644 --- a/subsystems/win32/csrss/include/conio.h +++ b/subsystems/win32/csrss/win32csr/conio.h @@ -46,14 +46,17 @@ typedef struct tagCSRSS_SCREEN_BUFFER USHORT VirtualY; /* top row of buffer being displayed, reported to callers */ CONSOLE_CURSOR_INFO CursorInfo; USHORT Mode; + LIST_ENTRY ListEntry; /* entry in console's list of buffers */ } CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER; +typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; + typedef struct tagCSRSS_CONSOLE_VTBL { VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer); - VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, RECT *Block, LONG CursorStartX, LONG CursorStartY, + VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, SMALL_RECT *Block, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length); - VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, RECT *Region); + VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, SMALL_RECT *Region); BOOL (WINAPI *SetCursorInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer); BOOL (WINAPI *SetScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, UINT OldCursorX, UINT OldCursorY); @@ -67,16 +70,25 @@ typedef struct tagCSRSS_CONSOLE_VTBL typedef struct tagCSRSS_CONSOLE { Object_t Header; /* Object header */ + LONG ReferenceCount; + CRITICAL_SECTION Lock; PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */ HANDLE ActiveEvent; LIST_ENTRY InputEvents; /* List head for input event queue */ - WORD WaitingChars; - WORD WaitingLines; /* number of chars and lines in input queue */ + PWCHAR LineBuffer; /* current line being input, in line buffered mode */ + WORD LineMaxSize; /* maximum size of line in characters (including CR+LF) */ + WORD LineSize; /* current size of line */ + WORD LinePos; /* current position within line */ + BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */ + BOOLEAN LineUpPressed; + LIST_ENTRY HistoryBuffers; + WORD HistoryBufferSize; /* size for newly created history buffers */ + WORD NumberOfHistoryBuffers; /* maximum number of history buffers allowed */ + BOOLEAN HistoryNoDup; /* remove old duplicate history entries */ + LIST_ENTRY BufferList; /* List of all screen buffers for this console */ PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */ WORD Mode; /* Console mode flags */ - WORD EchoCount; /* count of chars to echo, in line buffered mode */ UNICODE_STRING Title; /* Title of console */ - BOOL EarlyReturn; /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */ DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */ HWND hWindow; COORD Size; @@ -86,59 +98,30 @@ typedef struct tagCSRSS_CONSOLE PCSRSS_CONSOLE_VTBL Vtbl; LIST_ENTRY ProcessList; struct tagALIAS_HEADER *Aliases; + CONSOLE_SELECTION_INFO Selection; + BYTE PauseFlags; + HANDLE UnpauseEvent; } CSRSS_CONSOLE; -NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); -VOID WINAPI ConioDeleteConsole(Object_t *Object); -VOID WINAPI ConioDeleteScreenBuffer(Object_t *Buffer); -void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); -PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); -VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console); -VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData); -VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, - DWORD Timeout); +typedef struct ConsoleInput_t +{ + LIST_ENTRY ListEntry; + INPUT_RECORD InputEvent; +} ConsoleInput; -/* api/conio.c */ -CSR_API(CsrWriteConsole); -CSR_API(CsrAllocConsole); -CSR_API(CsrFreeConsole); -CSR_API(CsrReadConsole); -CSR_API(CsrConnectProcess); -CSR_API(CsrGetScreenBufferInfo); -CSR_API(CsrSetCursor); -CSR_API(CsrFillOutputChar); -CSR_API(CsrReadInputEvent); -CSR_API(CsrWriteConsoleOutputChar); -CSR_API(CsrWriteConsoleOutputAttrib); -CSR_API(CsrFillOutputAttrib); -CSR_API(CsrGetCursorInfo); -CSR_API(CsrSetCursorInfo); -CSR_API(CsrSetTextAttrib); -CSR_API(CsrSetConsoleMode); -CSR_API(CsrGetConsoleMode); -CSR_API(CsrCreateScreenBuffer); -CSR_API(CsrSetScreenBuffer); -CSR_API(CsrSetTitle); -CSR_API(CsrGetTitle); -CSR_API(CsrWriteConsoleOutput); -CSR_API(CsrFlushInputBuffer); -CSR_API(CsrScrollConsoleScreenBuffer); -CSR_API(CsrReadConsoleOutputChar); -CSR_API(CsrReadConsoleOutputAttrib); -CSR_API(CsrGetNumberOfConsoleInputEvents); -CSR_API(CsrPeekConsoleInput); -CSR_API(CsrReadConsoleOutput); -CSR_API(CsrWriteConsoleInput); -CSR_API(CsrHardwareStateProperty); -CSR_API(CsrGetConsoleWindow); -CSR_API(CsrSetConsoleIcon); -CSR_API(CsrGetConsoleCodePage); -CSR_API(CsrSetConsoleCodePage); -CSR_API(CsrGetConsoleOutputCodePage); -CSR_API(CsrSetConsoleOutputCodePage); -CSR_API(CsrGetProcessList); -CSR_API(CsrGenerateCtrlEvent); -CSR_API(CsrSetScreenBufferSize); +/* CONSOLE_SELECTION_INFO dwFlags values */ +#define CONSOLE_NO_SELECTION 0x0 +#define CONSOLE_SELECTION_IN_PROGRESS 0x1 +#define CONSOLE_SELECTION_NOT_EMPTY 0x2 +#define CONSOLE_MOUSE_SELECTION 0x4 +#define CONSOLE_MOUSE_DOWN 0x8 +/* HistoryFlags values */ +#define HISTORY_NO_DUP_FLAG 0x1 + +/* PauseFlags values (internal only) */ +#define PAUSED_FROM_KEYBOARD 0x1 +#define PAUSED_FROM_SCROLLBAR 0x2 +#define PAUSED_FROM_SELECTION 0x4 #define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff)) #define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region)) @@ -155,19 +138,79 @@ CSR_API(CsrSetScreenBufferSize); #define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon(Console, hWindowIcon) #define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer(Console, Buff, Size) -#define ConioRectHeight(Rect) \ - (((Rect)->top) > ((Rect)->bottom) ? 0 : ((Rect)->bottom) - ((Rect)->top) + 1) -#define ConioRectWidth(Rect) \ - (((Rect)->left) > ((Rect)->right) ? 0 : ((Rect)->right) - ((Rect)->left) + 1) +/* console.c */ +NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console); +VOID WINAPI ConioDeleteConsole(Object_t *Object); +VOID WINAPI CsrInitConsoleSupport(VOID); +VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags); +VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags); +VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData); +VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, + DWORD Timeout); +CSR_API(CsrAllocConsole); +CSR_API(CsrFreeConsole); +CSR_API(CsrSetConsoleMode); +CSR_API(CsrGetConsoleMode); +CSR_API(CsrSetTitle); +CSR_API(CsrGetTitle); +CSR_API(CsrHardwareStateProperty); +CSR_API(CsrGetConsoleWindow); +CSR_API(CsrSetConsoleIcon); +CSR_API(CsrGetConsoleCodePage); +CSR_API(CsrSetConsoleCodePage); +CSR_API(CsrGetConsoleOutputCodePage); +CSR_API(CsrSetConsoleOutputCodePage); +CSR_API(CsrGetProcessList); +CSR_API(CsrGenerateCtrlEvent); +CSR_API(CsrGetConsoleSelectionInfo); +/* coninput.c */ #define ConioLockConsole(ProcessData, Handle, Ptr, Access) \ Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC) #define ConioUnlockConsole(Console) \ Win32CsrUnlockObject((Object_t *) Console) +void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode); +CSR_API(CsrReadConsole); +CSR_API(CsrReadInputEvent); +CSR_API(CsrFlushInputBuffer); +CSR_API(CsrGetNumberOfConsoleInputEvents); +CSR_API(CsrPeekConsoleInput); +CSR_API(CsrWriteConsoleInput); + +/* conoutput.c */ +#define ConioRectHeight(Rect) \ + (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1) +#define ConioRectWidth(Rect) \ + (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) #define ConioLockScreenBuffer(ProcessData, Handle, Ptr, Access) \ Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_SCREEN_BUFFER_MAGIC) #define ConioUnlockScreenBuffer(Buff) \ Win32CsrUnlockObject((Object_t *) Buff) +PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y); +VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console); +NTSTATUS FASTCALL ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, + CHAR *Buffer, DWORD Length, BOOL Attrib); +NTSTATUS FASTCALL CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer); +VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer); + +CSR_API(CsrWriteConsole); +CSR_API(CsrGetScreenBufferInfo); +CSR_API(CsrSetCursor); +CSR_API(CsrWriteConsoleOutputChar); +CSR_API(CsrFillOutputChar); +CSR_API(CsrWriteConsoleOutputAttrib); +CSR_API(CsrFillOutputAttrib); +CSR_API(CsrGetCursorInfo); +CSR_API(CsrSetCursorInfo); +CSR_API(CsrSetTextAttrib); +CSR_API(CsrCreateScreenBuffer); +CSR_API(CsrSetScreenBuffer); +CSR_API(CsrWriteConsoleOutput); +CSR_API(CsrScrollConsoleScreenBuffer); +CSR_API(CsrReadConsoleOutputChar); +CSR_API(CsrReadConsoleOutputAttrib); +CSR_API(CsrReadConsoleOutput); +CSR_API(CsrSetScreenBufferSize); /* alias.c */ VOID IntDeleteAllAliases(struct tagALIAS_HEADER *RootHeader); @@ -178,4 +221,15 @@ CSR_API(CsrGetAllConsoleAliasesLength); CSR_API(CsrGetConsoleAliasesExes); CSR_API(CsrGetConsoleAliasesExesLength); +/* lineinput.c */ +struct tagHISTORY_BUFFER; +VOID FASTCALL HistoryDeleteBuffer(struct tagHISTORY_BUFFER *Hist); +CSR_API(CsrGetCommandHistoryLength); +CSR_API(CsrGetCommandHistory); +CSR_API(CsrExpungeCommandHistory); +CSR_API(CsrSetHistoryNumberCommands); +CSR_API(CsrGetHistoryInfo); +CSR_API(CsrSetHistoryInfo); +VOID FASTCALL LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent); + /* EOF */ diff --git a/subsystems/win32/csrss/win32csr/conoutput.c b/subsystems/win32/csrss/win32csr/conoutput.c new file mode 100644 index 00000000000..6b2a3a38358 --- /dev/null +++ b/subsystems/win32/csrss/win32csr/conoutput.c @@ -0,0 +1,1498 @@ +/* + * reactos/subsys/csrss/win32csr/conio.c + * + * Console I/O functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +/* GLOBALS *******************************************************************/ + +#define ConioInitRect(Rect, top, left, bottom, right) \ + ((Rect)->Top) = top; \ + ((Rect)->Left) = left; \ + ((Rect)->Bottom) = bottom; \ + ((Rect)->Right) = right + +#define ConioIsRectEmpty(Rect) \ + (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) + +#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1) + +/* FUNCTIONS *****************************************************************/ + +PBYTE FASTCALL +ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buff, ULONG X, ULONG Y) +{ + return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)]; +} + +static VOID FASTCALL +ClearLineBuffer(PCSRSS_SCREEN_BUFFER Buff) +{ + PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY); + UINT Pos; + + for (Pos = 0; Pos < Buff->MaxX; Pos++) + { + /* Fill the cell */ + *Ptr++ = ' '; + *Ptr++ = Buff->DefaultAttrib; + } +} + +NTSTATUS FASTCALL +CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, + PCSRSS_SCREEN_BUFFER Buffer) +{ + DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY); + + Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC; + Buffer->Header.Console = Console; + Buffer->Header.HandleCount = 0; + Buffer->ShowX = 0; + Buffer->ShowY = 0; + Buffer->VirtualY = 0; + Buffer->Buffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2); + if (NULL == Buffer->Buffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + ConioInitScreenBuffer(Console, Buffer); + /* initialize buffer to be empty with default attributes */ + for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) + { + ClearLineBuffer(Buffer); + } + Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + Buffer->CurrentX = 0; + Buffer->CurrentY = 0; + + InsertHeadList(&Console->BufferList, &Buffer->ListEntry); + return STATUS_SUCCESS; +} + +static VOID FASTCALL +ConioNextLine(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, UINT *ScrolledLines) +{ + /* If we hit bottom, slide the viewable screen */ + if (++Buff->CurrentY == Buff->MaxY) + { + Buff->CurrentY--; + if (++Buff->VirtualY == Buff->MaxY) + { + Buff->VirtualY = 0; + } + (*ScrolledLines)++; + ClearLineBuffer(Buff); + if (UpdateRect->Top != 0) + { + UpdateRect->Top--; + } + } + UpdateRect->Left = 0; + UpdateRect->Right = Buff->MaxX - 1; + UpdateRect->Bottom = Buff->CurrentY; +} + +NTSTATUS FASTCALL +ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, + CHAR *Buffer, DWORD Length, BOOL Attrib) +{ + UINT i; + PBYTE Ptr; + SMALL_RECT UpdateRect; + LONG CursorStartX, CursorStartY; + UINT ScrolledLines; + + CursorStartX = Buff->CurrentX; + CursorStartY = Buff->CurrentY; + UpdateRect.Left = Buff->MaxX; + UpdateRect.Top = Buff->CurrentY; + UpdateRect.Right = -1; + UpdateRect.Bottom = Buff->CurrentY; + ScrolledLines = 0; + + for (i = 0; i < Length; i++) + { + if (Buff->Mode & ENABLE_PROCESSED_OUTPUT) + { + /* --- LF --- */ + if (Buffer[i] == '\n') + { + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + continue; + } + /* --- BS --- */ + else if (Buffer[i] == '\b') + { + /* Only handle BS if we're not on the first pos of the first line */ + if (0 != Buff->CurrentX || 0 != Buff->CurrentY) + { + if (0 == Buff->CurrentX) + { + /* slide virtual position up */ + Buff->CurrentX = Buff->MaxX - 1; + Buff->CurrentY--; + UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY); + } + else + { + Buff->CurrentX--; + } + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr[0] = ' '; + Ptr[1] = Buff->DefaultAttrib; + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + } + continue; + } + /* --- CR --- */ + else if (Buffer[i] == '\r') + { + Buff->CurrentX = 0; + UpdateRect.Left = min(UpdateRect.Left, (LONG) Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + continue; + } + /* --- TAB --- */ + else if (Buffer[i] == '\t') + { + UINT EndX; + + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + EndX = (Buff->CurrentX + 8) & ~7; + if (EndX > Buff->MaxX) + { + EndX = Buff->MaxX; + } + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + while (Buff->CurrentX < EndX) + { + *Ptr++ = ' '; + *Ptr++ = Buff->DefaultAttrib; + Buff->CurrentX++; + } + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX - 1); + if (Buff->CurrentX == Buff->MaxX) + { + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + { + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + } + else + { + Buff->CurrentX--; + } + } + continue; + } + } + UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX); + UpdateRect.Right = max(UpdateRect.Right, (LONG) Buff->CurrentX); + Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY); + Ptr[0] = Buffer[i]; + if (Attrib) + { + Ptr[1] = Buff->DefaultAttrib; + } + Buff->CurrentX++; + if (Buff->CurrentX == Buff->MaxX) + { + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + { + Buff->CurrentX = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + } + else + { + Buff->CurrentX = CursorStartX; + } + } + } + + if (! ConioIsRectEmpty(&UpdateRect) && Buff == Console->ActiveBuffer) + { + ConioWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, ScrolledLines, + Buffer, Length); + } + + return STATUS_SUCCESS; +} + +__inline BOOLEAN ConioGetIntersection( + SMALL_RECT *Intersection, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) +{ + if (ConioIsRectEmpty(Rect1) || + (ConioIsRectEmpty(Rect2)) || + (Rect1->Top > Rect2->Bottom) || + (Rect1->Left > Rect2->Right) || + (Rect1->Bottom < Rect2->Top) || + (Rect1->Right < Rect2->Left)) + { + /* The rectangles do not intersect */ + ConioInitRect(Intersection, 0, -1, 0, -1); + return FALSE; + } + + ConioInitRect(Intersection, + max(Rect1->Top, Rect2->Top), + max(Rect1->Left, Rect2->Left), + min(Rect1->Bottom, Rect2->Bottom), + min(Rect1->Right, Rect2->Right)); + + return TRUE; +} + +__inline BOOLEAN ConioGetUnion( + SMALL_RECT *Union, + SMALL_RECT *Rect1, + SMALL_RECT *Rect2) +{ + if (ConioIsRectEmpty(Rect1)) + { + if (ConioIsRectEmpty(Rect2)) + { + ConioInitRect(Union, 0, -1, 0, -1); + return FALSE; + } + else + { + *Union = *Rect2; + } + } + else if (ConioIsRectEmpty(Rect2)) + { + *Union = *Rect1; + } + else + { + ConioInitRect(Union, + min(Rect1->Top, Rect2->Top), + min(Rect1->Left, Rect2->Left), + max(Rect1->Bottom, Rect2->Bottom), + max(Rect1->Right, Rect2->Right)); + } + + return TRUE; +} + +/* Move from one rectangle to another. We must be careful about the order that + * this is done, to avoid overwriting parts of the source before they are moved. */ +static VOID FASTCALL +ConioMoveRegion(PCSRSS_SCREEN_BUFFER ScreenBuffer, + SMALL_RECT *SrcRegion, + SMALL_RECT *DstRegion, + SMALL_RECT *ClipRegion, + WORD Fill) +{ + int Width = ConioRectWidth(SrcRegion); + int Height = ConioRectHeight(SrcRegion); + int SX, SY; + int DX, DY; + int XDelta, YDelta; + int i, j; + + SY = SrcRegion->Top; + DY = DstRegion->Top; + YDelta = 1; + if (SY < DY) + { + /* Moving down: work from bottom up */ + SY = SrcRegion->Bottom; + DY = DstRegion->Bottom; + YDelta = -1; + } + for (i = 0; i < Height; i++) + { + PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY); + PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY); + + SX = SrcRegion->Left; + DX = DstRegion->Left; + XDelta = 1; + if (SX < DX) + { + /* Moving right: work from right to left */ + SX = SrcRegion->Right; + DX = DstRegion->Right; + XDelta = -1; + } + for (j = 0; j < Width; j++) + { + WORD Cell = SRow[SX]; + if (SX >= ClipRegion->Left && SX <= ClipRegion->Right + && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) + { + SRow[SX] = Fill; + } + if (DX >= ClipRegion->Left && DX <= ClipRegion->Right + && DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) + { + DRow[DX] = Cell; + } + SX += XDelta; + DX += XDelta; + } + SY += YDelta; + DY += YDelta; + } +} + +CSR_API(CsrWriteConsole) +{ + NTSTATUS Status; + PCHAR Buffer; + PCSRSS_SCREEN_BUFFER Buff; + PCSRSS_CONSOLE Console; + DWORD Written = 0; + ULONG Length; + ULONG CharSize = (Request->Data.WriteConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + DPRINT("CsrWriteConsole\n"); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + + (Request->Data.WriteConsoleRequest.NrCharactersToWrite * CharSize)) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + if (Console->UnpauseEvent) + { + Status = NtDuplicateObject(GetCurrentProcess(), Console->UnpauseEvent, + ProcessData->Process, &Request->Data.WriteConsoleRequest.UnpauseEvent, + SYNCHRONIZE, 0, 0); + ConioUnlockScreenBuffer(Buff); + return NT_SUCCESS(Status) ? STATUS_PENDING : Status; + } + + if(Request->Data.WriteConsoleRequest.Unicode) + { + Length = WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, + NULL, 0, NULL, NULL); + Buffer = RtlAllocateHeap(GetProcessHeap(), 0, Length); + if (Buffer) + { + WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleRequest.Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, + Buffer, Length, NULL, NULL); + } + else + { + Status = STATUS_NO_MEMORY; + } + } + else + { + Buffer = (PCHAR)Request->Data.WriteConsoleRequest.Buffer; + } + + if (Buffer) + { + if (NT_SUCCESS(Status)) + { + Status = ConioWriteConsole(Console, Buff, Buffer, + Request->Data.WriteConsoleRequest.NrCharactersToWrite, TRUE); + if (NT_SUCCESS(Status)) + { + Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite; + } + } + if (Request->Data.WriteConsoleRequest.Unicode) + { + RtlFreeHeap(GetProcessHeap(), 0, Buffer); + } + } + ConioUnlockScreenBuffer(Buff); + + Request->Data.WriteConsoleRequest.NrCharactersWritten = Written; + + return Status; +} + +VOID WINAPI +ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer) +{ + PCSRSS_CONSOLE Console = Buffer->Header.Console; + + RemoveEntryList(&Buffer->ListEntry); + if (Buffer == Console->ActiveBuffer) + { + /* Deleted active buffer; switch to most recently created */ + Console->ActiveBuffer = NULL; + if (!IsListEmpty(&Console->BufferList)) + { + Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CSRSS_SCREEN_BUFFER, ListEntry); + ConioDrawConsole(Console); + } + } + + HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); + HeapFree(Win32CsrApiHeap, 0, Buffer); +} + +VOID FASTCALL +ConioDrawConsole(PCSRSS_CONSOLE Console) +{ + SMALL_RECT Region; + + ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1); + + ConioDrawRegion(Console, &Region); +} + +CSR_API(CsrGetScreenBufferInfo) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PCONSOLE_SCREEN_BUFFER_INFO pInfo; + + DPRINT("CsrGetScreenBufferInfo\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + pInfo = &Request->Data.ScreenBufferInfoRequest.Info; + pInfo->dwSize.X = Buff->MaxX; + pInfo->dwSize.Y = Buff->MaxY; + pInfo->dwCursorPosition.X = Buff->CurrentX; + pInfo->dwCursorPosition.Y = Buff->CurrentY; + pInfo->wAttributes = Buff->DefaultAttrib; + pInfo->srWindow.Left = Buff->ShowX; + pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1; + pInfo->srWindow.Top = Buff->ShowY; + pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1; + pInfo->dwMaximumWindowSize.X = Buff->MaxX; + pInfo->dwMaximumWindowSize.Y = Buff->MaxY; + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetCursor) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + LONG OldCursorX, OldCursorY; + LONG NewCursorX, NewCursorY; + + DPRINT("CsrSetCursor\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + NewCursorX = Request->Data.SetCursorRequest.Position.X; + NewCursorY = Request->Data.SetCursorRequest.Position.Y; + if (NewCursorX < 0 || NewCursorX >= Buff->MaxX || + NewCursorY < 0 || NewCursorY >= Buff->MaxY) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_INVALID_PARAMETER; + } + OldCursorX = Buff->CurrentX; + OldCursorY = Buff->CurrentY; + Buff->CurrentX = NewCursorX; + Buff->CurrentY = NewCursorY; + if (Buff == Console->ActiveBuffer) + { + if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +static VOID FASTCALL +ConioComputeUpdateRect(PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *UpdateRect, COORD *Start, UINT Length) +{ + if (Buff->MaxX <= Start->X + Length) + { + UpdateRect->Left = 0; + } + else + { + UpdateRect->Left = Start->X; + } + if (Buff->MaxX <= Start->X + Length) + { + UpdateRect->Right = Buff->MaxX - 1; + } + else + { + UpdateRect->Right = Start->X + Length - 1; + } + UpdateRect->Top = Start->Y; + UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX; + if (Buff->MaxY <= UpdateRect->Bottom) + { + UpdateRect->Bottom = Buff->MaxY - 1; + } +} + +CSR_API(CsrWriteConsoleOutputChar) +{ + NTSTATUS Status; + PCHAR String, tmpString = NULL; + PBYTE Buffer; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD X, Y, Length, CharSize, Written = 0; + SMALL_RECT UpdateRect; + + DPRINT("CsrWriteConsoleOutputChar\n"); + + CharSize = (Request->Data.WriteConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + + (Request->Data.WriteConsoleOutputCharRequest.Length * CharSize)) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if (NT_SUCCESS(Status)) + { + Console = Buff->Header.Console; + if(Request->Data.WriteConsoleOutputCharRequest.Unicode) + { + Length = WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, + Request->Data.WriteConsoleOutputCharRequest.Length, + NULL, 0, NULL, NULL); + tmpString = String = RtlAllocateHeap(GetProcessHeap(), 0, Length); + if (String) + { + WideCharToMultiByte(Console->OutputCodePage, 0, + (PWCHAR)Request->Data.WriteConsoleOutputCharRequest.String, + Request->Data.WriteConsoleOutputCharRequest.Length, + String, Length, NULL, NULL); + } + else + { + Status = STATUS_NO_MEMORY; + } + } + else + { + String = (PCHAR)Request->Data.WriteConsoleOutputCharRequest.String; + } + + if (String) + { + if (NT_SUCCESS(Status)) + { + X = Request->Data.WriteConsoleOutputCharRequest.Coord.X; + Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputCharRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + while (Length--) + { + *Buffer = *String++; + Written++; + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer; + } + X = 0; + } + } + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputCharRequest.Coord, + Request->Data.WriteConsoleOutputCharRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X; + Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; + + } + if (Request->Data.WriteConsoleRequest.Unicode) + { + RtlFreeHeap(GetProcessHeap(), 0, tmpString); + } + } + ConioUnlockScreenBuffer(Buff); + } + Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written; + return Status; +} + +CSR_API(CsrFillOutputChar) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD X, Y, Length, Written = 0; + CHAR Char; + PBYTE Buffer; + SMALL_RECT UpdateRect; + + DPRINT("CsrFillOutputChar\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + X = Request->Data.FillOutputRequest.Position.X; + Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) % Buff->MaxY; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + if(Request->Data.FillOutputRequest.Unicode) + ConsoleUnicodeCharToAnsiChar(Console, &Char, &Request->Data.FillOutputRequest.Char.UnicodeChar); + else + Char = Request->Data.FillOutputRequest.Char.AsciiChar; + Length = Request->Data.FillOutputRequest.Length; + while (Length--) + { + *Buffer = Char; + Buffer += 2; + Written++; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer; + } + X = 0; + } + } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputRequest.Position, + Request->Data.FillOutputRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + ConioUnlockScreenBuffer(Buff); + Length = Request->Data.FillOutputRequest.Length; + Request->Data.FillOutputRequest.NrCharactersWritten = Length; + return STATUS_SUCCESS; +} + +CSR_API(CsrWriteConsoleOutputAttrib) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer; + PWORD Attribute; + int X, Y, Length; + NTSTATUS Status; + SMALL_RECT UpdateRect; + + DPRINT("CsrWriteConsoleOutputAttrib\n"); + + if (Request->Header.u1.s1.TotalLength + < CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + + Request->Data.WriteConsoleOutputAttribRequest.Length * sizeof(WORD)) + { + DPRINT1("Invalid request size\n"); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + return STATUS_INVALID_PARAMETER; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X; + Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputAttribRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; + Attribute = Request->Data.WriteConsoleOutputAttribRequest.Attribute; + while (Length--) + { + *Buffer = (UCHAR)(*Attribute++); + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer + 1; + } + X = 0; + } + } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.WriteConsoleOutputAttribRequest.Coord, + Request->Data.WriteConsoleOutputAttribRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X; + Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY; + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrFillOutputAttrib) +{ + PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer; + NTSTATUS Status; + int X, Y, Length; + UCHAR Attr; + SMALL_RECT UpdateRect; + PCSRSS_CONSOLE Console; + + DPRINT("CsrFillOutputAttrib\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + X = Request->Data.FillOutputAttribRequest.Coord.X; + Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) % Buff->MaxY; + Length = Request->Data.FillOutputAttribRequest.Length; + Attr = Request->Data.FillOutputAttribRequest.Attribute; + Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; + while (Length--) + { + *Buffer = Attr; + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer + 1; + } + X = 0; + } + } + + if (Buff == Console->ActiveBuffer) + { + ConioComputeUpdateRect(Buff, &UpdateRect, &Request->Data.FillOutputAttribRequest.Coord, + Request->Data.FillOutputAttribRequest.Length); + ConioDrawRegion(Console, &UpdateRect); + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrGetCursorInfo) +{ + PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + + DPRINT("CsrGetCursorInfo\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.GetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Request->Data.GetCursorInfoRequest.Info.bVisible = Buff->CursorInfo.bVisible; + Request->Data.GetCursorInfoRequest.Info.dwSize = Buff->CursorInfo.dwSize; + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetCursorInfo) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Size; + BOOL Visible; + NTSTATUS Status; + + DPRINT("CsrSetCursorInfo\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Size = Request->Data.SetCursorInfoRequest.Info.dwSize; + Visible = Request->Data.SetCursorInfoRequest.Info.bVisible; + if (Size < 1) + { + Size = 1; + } + if (100 < Size) + { + Size = 100; + } + + if (Size != Buff->CursorInfo.dwSize + || (Visible && ! Buff->CursorInfo.bVisible) || (! Visible && Buff->CursorInfo.bVisible)) + { + Buff->CursorInfo.dwSize = Size; + Buff->CursorInfo.bVisible = Visible; + + if (! ConioSetCursorInfo(Console, Buff)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetTextAttrib) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetTextAttrib\n"); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib; + if (Buff == Console->ActiveBuffer) + { + if (! ConioUpdateScreenInfo(Console, Buff)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_UNSUCCESSFUL; + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrCreateScreenBuffer) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + NTSTATUS Status; + + DPRINT("CsrCreateScreenBuffer\n"); + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Buff = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + + if (Buff != NULL) + { + if (Console->ActiveBuffer) + { + Buff->MaxX = Console->ActiveBuffer->MaxX; + Buff->MaxY = Console->ActiveBuffer->MaxY; + Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible; + Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize; + } + else + { + Buff->CursorInfo.bVisible = TRUE; + Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + } + + if (Buff->MaxX == 0) + { + Buff->MaxX = 80; + } + + if (Buff->MaxY == 0) + { + Buff->MaxY = 25; + } + + Status = CsrInitConsoleScreenBuffer(Console, Buff); + if (NT_SUCCESS(Status)) + { + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.CreateScreenBufferRequest.OutputHandle, + &Buff->Header, + Request->Data.CreateScreenBufferRequest.Access, + Request->Data.CreateScreenBufferRequest.Inheritable, + Request->Data.CreateScreenBufferRequest.ShareMode); + } + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + + ConioUnlockConsole(Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; +} + +CSR_API(CsrSetScreenBuffer) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetScreenBuffer\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + if (Buff == Console->ActiveBuffer) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + + /* If old buffer has no handles, it's now unreferenced */ + if (Console->ActiveBuffer->Header.HandleCount == 0) + { + ConioDeleteScreenBuffer(Console->ActiveBuffer); + } + /* tie console to new buffer */ + Console->ActiveBuffer = Buff; + /* Redraw the console */ + ConioDrawConsole(Console); + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrWriteConsoleOutput) +{ + SHORT i, X, Y, SizeX, SizeY; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + SMALL_RECT ScreenBuffer; + CHAR_INFO* CurCharInfo; + SMALL_RECT WriteRegion; + CHAR_INFO* CharInfo; + COORD BufferCoord; + COORD BufferSize; + NTSTATUS Status; + PBYTE Ptr; + + DPRINT("CsrWriteConsoleOutput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, + Request->Data.WriteConsoleOutputRequest.ConsoleHandle, + &Buff, + GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize; + BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord; + CharInfo = Request->Data.WriteConsoleOutputRequest.CharInfo; + if (!Win32CsrValidateBuffer(ProcessData, CharInfo, + BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_ACCESS_VIOLATION; + } + WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion; + + SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); + SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); + WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + WriteRegion.Right = WriteRegion.Left + SizeX - 1; + + /* Make sure WriteRegion is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) + { + ConioUnlockScreenBuffer(Buff); + + /* It is okay to have a WriteRegion completely outside the screen buffer. + No data is written then. */ + return STATUS_SUCCESS; + } + + for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) + { + CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; + Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); + for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) + { + CHAR AsciiChar; + if (Request->Data.WriteConsoleOutputRequest.Unicode) + { + ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar); + } + else + { + AsciiChar = CurCharInfo->Char.AsciiChar; + } + *Ptr++ = AsciiChar; + *Ptr++ = CurCharInfo->Attributes; + CurCharInfo++; + } + } + + ConioDrawRegion(Console, &WriteRegion); + + ConioUnlockScreenBuffer(Buff); + + Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.Left + SizeX - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Left = WriteRegion.Left; + Request->Data.WriteConsoleOutputRequest.WriteRegion.Top = WriteRegion.Top; + + return STATUS_SUCCESS; +} + +CSR_API(CsrScrollConsoleScreenBuffer) +{ + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + SMALL_RECT ScreenBuffer; + SMALL_RECT SrcRegion; + SMALL_RECT DstRegion; + SMALL_RECT UpdateRegion; + SMALL_RECT ScrollRectangle; + SMALL_RECT ClipRectangle; + NTSTATUS Status; + HANDLE ConsoleHandle; + BOOLEAN UseClipRectangle; + COORD DestinationOrigin; + CHAR_INFO Fill; + CHAR FillChar; + + DPRINT("CsrScrollConsoleScreenBuffer\n"); + + ConsoleHandle = Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle; + UseClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle; + DestinationOrigin = Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin; + Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + ScrollRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle; + + /* Make sure source rectangle is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); + if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + + /* If the source was clipped on the left or top, adjust the destination accordingly */ + if (ScrollRectangle.Left < 0) + { + DestinationOrigin.X -= ScrollRectangle.Left; + } + if (ScrollRectangle.Top < 0) + { + DestinationOrigin.Y -= ScrollRectangle.Top; + } + + if (UseClipRectangle) + { + ClipRectangle = Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle; + if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + } + else + { + ClipRectangle = ScreenBuffer; + } + + ConioInitRect(&DstRegion, + DestinationOrigin.Y, + DestinationOrigin.X, + DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, + DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); + + if (Request->Data.ScrollConsoleScreenBufferRequest.Unicode) + ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar); + else + FillChar = Fill.Char.AsciiChar; + + ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar); + + if (Buff == Console->ActiveBuffer) + { + ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); + if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) + { + /* Draw update region */ + ConioDrawRegion(Console, &UpdateRegion); + } + } + + ConioUnlockScreenBuffer(Buff); + + return STATUS_SUCCESS; +} + +CSR_API(CsrReadConsoleOutputChar) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Xpos, Ypos; + PCHAR ReadBuffer; + DWORD i; + ULONG CharSize; + CHAR Char; + + DPRINT("CsrReadConsoleOutputChar\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + ReadBuffer = Request->Data.ReadConsoleOutputCharRequest.String; + + CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR)); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X; + Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + + for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) + { + Char = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX)]; + + if(Request->Data.ReadConsoleOutputCharRequest.Unicode) + { + ConsoleAnsiCharToUnicodeChar(Console, (WCHAR*)ReadBuffer, &Char); + ReadBuffer += sizeof(WCHAR); + } + else + *(ReadBuffer++) = Char; + + Xpos++; + + if (Xpos == Buff->MaxX) + { + Xpos = 0; + Ypos++; + + if (Ypos == Buff->MaxY) + { + Ypos = 0; + } + } + } + + *ReadBuffer = 0; + Request->Data.ReadConsoleOutputCharRequest.EndCoord.X = Xpos; + Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + + ConioUnlockScreenBuffer(Buff); + + Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize; + if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize + CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + } + + return STATUS_SUCCESS; +} + + +CSR_API(CsrReadConsoleOutputAttrib) +{ + NTSTATUS Status; + PCSRSS_SCREEN_BUFFER Buff; + DWORD Xpos, Ypos; + PWORD ReadBuffer; + DWORD i; + DWORD CurrentLength; + + DPRINT("CsrReadConsoleOutputAttrib\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = Request->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + ReadBuffer = Request->Data.ReadConsoleOutputAttribRequest.Attribute; + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X; + Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + Buff->VirtualY) % Buff->MaxY; + + for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) + { + *ReadBuffer = Buff->Buffer[(Xpos * 2) + (Ypos * 2 * Buff->MaxX) + 1]; + + ReadBuffer++; + Xpos++; + + if (Xpos == Buff->MaxX) + { + Xpos = 0; + Ypos++; + + if (Ypos == Buff->MaxY) + { + Ypos = 0; + } + } + } + + *ReadBuffer = 0; + + Request->Data.ReadConsoleOutputAttribRequest.EndCoord.X = Xpos; + Request->Data.ReadConsoleOutputAttribRequest.EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY; + + ConioUnlockScreenBuffer(Buff); + + CurrentLength = CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + + Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead * sizeof(WORD); + if (CurrentLength > sizeof(CSR_API_MESSAGE)) + { + Request->Header.u1.s1.TotalLength = CurrentLength; + Request->Header.u1.s1.DataLength = CurrentLength - sizeof(PORT_MESSAGE); + } + + return STATUS_SUCCESS; +} + +CSR_API(CsrReadConsoleOutput) +{ + PCHAR_INFO CharInfo; + PCHAR_INFO CurCharInfo; + PCSRSS_SCREEN_BUFFER Buff; + DWORD SizeX, SizeY; + NTSTATUS Status; + COORD BufferSize; + COORD BufferCoord; + SMALL_RECT ReadRegion; + SMALL_RECT ScreenRect; + DWORD i; + PBYTE Ptr; + LONG X, Y; + UINT CodePage; + + DPRINT("CsrReadConsoleOutput\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.ReadConsoleOutputRequest.ConsoleHandle, &Buff, GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + CharInfo = Request->Data.ReadConsoleOutputRequest.CharInfo; + ReadRegion = Request->Data.ReadConsoleOutputRequest.ReadRegion; + BufferSize = Request->Data.ReadConsoleOutputRequest.BufferSize; + BufferCoord = Request->Data.ReadConsoleOutputRequest.BufferCoord; + + /* FIXME: Is this correct? */ + CodePage = ProcessData->Console->OutputCodePage; + + if (!Win32CsrValidateBuffer(ProcessData, CharInfo, + BufferSize.X * BufferSize.Y, sizeof(CHAR_INFO))) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_ACCESS_VIOLATION; + } + + SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); + SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); + ReadRegion.Bottom = ReadRegion.Top + SizeY; + ReadRegion.Right = ReadRegion.Left + SizeX; + + ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX); + if (! ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) + { + ConioUnlockScreenBuffer(Buff); + return STATUS_SUCCESS; + } + + for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) + { + CurCharInfo = CharInfo + (i * BufferSize.X); + + Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); + for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) + { + if (Request->Data.ReadConsoleOutputRequest.Unicode) + { + MultiByteToWideChar(CodePage, 0, + (PCHAR)Ptr++, 1, + &CurCharInfo->Char.UnicodeChar, 1); + } + else + { + CurCharInfo->Char.AsciiChar = *Ptr++; + } + CurCharInfo->Attributes = *Ptr++; + ++CurCharInfo; + } + } + + ConioUnlockScreenBuffer(Buff); + + Request->Data.ReadConsoleOutputRequest.ReadRegion.Right = ReadRegion.Left + SizeX - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Left = ReadRegion.Left; + Request->Data.ReadConsoleOutputRequest.ReadRegion.Top = ReadRegion.Top; + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetScreenBufferSize) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockScreenBuffer(ProcessData, Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + Console = Buff->Header.Console; + + Status = ConioResizeBuffer(Console, Buff, Request->Data.SetScreenBufferSize.Size); + ConioUnlockScreenBuffer(Buff); + + return Status; +} + +/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/console.c b/subsystems/win32/csrss/win32csr/console.c new file mode 100644 index 00000000000..6db2a2ec34a --- /dev/null +++ b/subsystems/win32/csrss/win32csr/console.c @@ -0,0 +1,848 @@ +/* + * reactos/subsys/csrss/win32csr/conio.c + * + * Console I/O functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS FASTCALL +ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Console) +{ + PCSRSS_CONSOLE ProcessConsole; + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + ProcessConsole = ProcessData->Console; + + if (!ProcessConsole) + { + *Console = NULL; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; + } + + InterlockedIncrement(&ProcessConsole->ReferenceCount); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + EnterCriticalSection(&(ProcessConsole->Lock)); + *Console = ProcessConsole; + + return STATUS_SUCCESS; +} + +VOID FASTCALL +ConioConsoleCtrlEventTimeout(DWORD Event, PCSRSS_PROCESS_DATA ProcessData, DWORD Timeout) +{ + HANDLE Thread; + + DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ProcessId); + + if (ProcessData->CtrlDispatcher) + { + + Thread = CreateRemoteThread(ProcessData->Process, NULL, 0, + (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher, + UlongToPtr(Event), 0, NULL); + if (NULL == Thread) + { + DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError()); + return; + } + WaitForSingleObject(Thread, Timeout); + CloseHandle(Thread); + } +} + +VOID FASTCALL +ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData) +{ + ConioConsoleCtrlEventTimeout(Event, ProcessData, 0); +} + +static NTSTATUS WINAPI +CsrInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) +{ + NTSTATUS Status; + SECURITY_ATTRIBUTES SecurityAttributes; + PCSRSS_SCREEN_BUFFER NewBuffer; + BOOL GuiMode; + + Console->Title.MaximumLength = Console->Title.Length = 0; + Console->Title.Buffer = NULL; + + //FIXME + RtlCreateUnicodeString(&Console->Title, L"Command Prompt"); + + Console->ReferenceCount = 0; + Console->LineBuffer = NULL; + Console->Header.Type = CONIO_CONSOLE_MAGIC; + Console->Header.Console = Console; + Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; + InitializeListHead(&Console->BufferList); + Console->ActiveBuffer = NULL; + InitializeListHead(&Console->InputEvents); + InitializeListHead(&Console->HistoryBuffers); + Console->CodePage = GetOEMCP(); + Console->OutputCodePage = GetOEMCP(); + + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.lpSecurityDescriptor = NULL; + SecurityAttributes.bInheritHandle = TRUE; + + Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); + if (NULL == Console->ActiveEvent) + { + RtlFreeUnicodeString(&Console->Title); + return STATUS_UNSUCCESSFUL; + } + Console->PrivateData = NULL; + InitializeCriticalSection(&Console->Lock); + + GuiMode = DtbgIsDesktopVisible(); + + /* allocate console screen buffer */ + NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER)); + if (NULL == NewBuffer) + { + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + return STATUS_INSUFFICIENT_RESOURCES; + } + /* init screen buffer with defaults */ + NewBuffer->CursorInfo.bVisible = TRUE; + NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + /* make console active, and insert into console list */ + Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; + + if (! GuiMode) + { + Status = TuiInitConsole(Console); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); + GuiMode = TRUE; + } + } + if (GuiMode) + { + Status = GuiInitConsole(Console, Visible); + if (! NT_SUCCESS(Status)) + { + HeapFree(Win32CsrApiHeap,0, NewBuffer); + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + DPRINT1("GuiInitConsole: failed\n"); + return Status; + } + } + + Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); + if (! NT_SUCCESS(Status)) + { + ConioCleanupConsole(Console); + RtlFreeUnicodeString(&Console->Title); + DeleteCriticalSection(&Console->Lock); + CloseHandle(Console->ActiveEvent); + HeapFree(Win32CsrApiHeap, 0, NewBuffer); + DPRINT1("CsrInitConsoleScreenBuffer: failed\n"); + return Status; + } + + /* copy buffer contents to screen */ + ConioDrawConsole(Console); + + return STATUS_SUCCESS; +} + +CSR_API(CsrAllocConsole) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN NewConsole = FALSE; + + DPRINT("CsrAllocConsole\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (ProcessData->Console) + { + DPRINT1("Process already has a console\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_PARAMETER; + } + + /* If we don't need a console, then get out of here */ + if (!Request->Data.AllocConsoleRequest.ConsoleNeeded) + { + DPRINT("No console needed\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_SUCCESS; + } + + /* If we already have one, then don't create a new one... */ + if (!Request->Data.AllocConsoleRequest.Console || + Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole) + { + /* Allocate a console structure */ + NewConsole = TRUE; + Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE)); + if (NULL == Console) + { + DPRINT1("Not enough memory for console\n"); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_NO_MEMORY; + } + /* initialize list head */ + InitializeListHead(&Console->ProcessList); + /* insert process data required for GUI initialization */ + InsertHeadList(&Console->ProcessList, &ProcessData->ProcessEntry); + /* Initialize the Console */ + Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.Visible); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Console init failed\n"); + HeapFree(Win32CsrApiHeap, 0, Console); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + } + else + { + /* Reuse our current console */ + Console = Request->Data.AllocConsoleRequest.Console; + } + + /* Set the Process Console */ + ProcessData->Console = Console; + + /* Return it to the caller */ + Request->Data.AllocConsoleRequest.Console = Console; + + /* Add a reference count because the process is tied to the console */ + _InterlockedIncrement(&Console->ReferenceCount); + + if (NewConsole || !ProcessData->bInheritHandles) + { + /* Insert the Objects */ + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.AllocConsoleRequest.InputHandle, + &Console->Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed to insert object\n"); + ConioDeleteConsole((Object_t *) Console); + ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.AllocConsoleRequest.OutputHandle, + &Console->ActiveBuffer->Header, + GENERIC_READ | GENERIC_WRITE, + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to insert object\n"); + ConioDeleteConsole((Object_t *) Console); + Win32CsrReleaseObject(ProcessData, + Request->Data.AllocConsoleRequest.InputHandle); + ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + } + + /* Duplicate the Event */ + if (!DuplicateHandle(GetCurrentProcess(), + ProcessData->Console->ActiveEvent, + ProcessData->Process, + &ProcessData->ConsoleEvent, + EVENT_ALL_ACCESS, + FALSE, + 0)) + { + DPRINT1("DuplicateHandle() failed: %d\n", GetLastError); + ConioDeleteConsole((Object_t *) Console); + if (NewConsole || !ProcessData->bInheritHandles) + { + Win32CsrReleaseObject(ProcessData, + Request->Data.AllocConsoleRequest.OutputHandle); + Win32CsrReleaseObject(ProcessData, + Request->Data.AllocConsoleRequest.InputHandle); + } + ProcessData->Console = 0; + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; + } + + /* Set the Ctrl Dispatcher */ + ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher; + DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher); + + if (!NewConsole) + { + /* Insert into the list if it has not been added */ + InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry); + } + + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_SUCCESS; +} + +CSR_API(CsrFreeConsole) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + return Win32CsrReleaseConsole(ProcessData); +} + +VOID WINAPI +ConioDeleteConsole(Object_t *Object) +{ + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object; + ConsoleInput *Event; + + DPRINT("ConioDeleteConsole\n"); + + /* Drain input event queue */ + while (Console->InputEvents.Flink != &Console->InputEvents) + { + Event = (ConsoleInput *) Console->InputEvents.Flink; + Console->InputEvents.Flink = Console->InputEvents.Flink->Flink; + Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents; + HeapFree(Win32CsrApiHeap, 0, Event); + } + + ConioCleanupConsole(Console); + if (Console->LineBuffer) + RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer); + while (!IsListEmpty(&Console->HistoryBuffers)) + HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink); + + ConioDeleteScreenBuffer(Console->ActiveBuffer); + if (!IsListEmpty(&Console->BufferList)) + { + DPRINT1("BUG: screen buffer list not empty\n"); + } + + CloseHandle(Console->ActiveEvent); + if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); + DeleteCriticalSection(&Console->Lock); + RtlFreeUnicodeString(&Console->Title); + IntDeleteAllAliases(Console->Aliases); + HeapFree(Win32CsrApiHeap, 0, Console); +} + +VOID WINAPI +CsrInitConsoleSupport(VOID) +{ + DPRINT("CSR: CsrInitConsoleSupport()\n"); + + /* Should call LoadKeyboardLayout */ +} + +VOID FASTCALL +ConioPause(PCSRSS_CONSOLE Console, UINT Flags) +{ + Console->PauseFlags |= Flags; + if (!Console->UnpauseEvent) + Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +VOID FASTCALL +ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags) +{ + Console->PauseFlags &= ~Flags; + if (Console->PauseFlags == 0 && Console->UnpauseEvent) + { + SetEvent(Console->UnpauseEvent); + CloseHandle(Console->UnpauseEvent); + Console->UnpauseEvent = NULL; + } +} + +CSR_API(CsrSetConsoleMode) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetConsoleMode\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = Win32CsrLockObject(ProcessData, + Request->Data.SetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_WRITE, 0); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Buff = (PCSRSS_SCREEN_BUFFER)Console; + if (CONIO_CONSOLE_MAGIC == Console->Header.Type) + { + Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID; + } + else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type) + { + Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID; + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + Win32CsrUnlockObject((Object_t *)Console); + + return Status; +} + +CSR_API(CsrGetConsoleMode) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */ + + DPRINT("CsrGetConsoleMode\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, + (Object_t **) &Console, GENERIC_READ, 0); + if (! NT_SUCCESS(Status)) + { + return Status; + } + Status = STATUS_SUCCESS; + Buff = (PCSRSS_SCREEN_BUFFER) Console; + if (CONIO_CONSOLE_MAGIC == Console->Header.Type) + { + Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode; + } + else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type) + { + Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode; + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + Win32CsrUnlockObject((Object_t *)Console); + return Status; +} + +CSR_API(CsrSetTitle) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + PWCHAR Buffer; + + DPRINT("CsrSetTitle\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + if (!Win32CsrValidateBuffer(ProcessData, Request->Data.SetTitleRequest.Title, + Request->Data.SetTitleRequest.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if(NT_SUCCESS(Status)) + { + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length); + if (Buffer) + { + /* copy title to console */ + RtlFreeUnicodeString(&Console->Title); + Console->Title.Buffer = Buffer; + Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length; + memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length); + if (! ConioChangeTitle(Console)) + { + Status = STATUS_UNSUCCESSFUL; + } + else + { + Status = STATUS_SUCCESS; + } + } + else + { + Status = STATUS_NO_MEMORY; + } + ConioUnlockConsole(Console); + } + + return Status; +} + +CSR_API(CsrGetTitle) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + DWORD Length; + + DPRINT("CsrGetTitle\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (!Win32CsrValidateBuffer(ProcessData, Request->Data.GetTitleRequest.Title, + Request->Data.GetTitleRequest.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Can't get console\n"); + return Status; + } + + /* Copy title of the console to the user title buffer */ + if (Request->Data.GetTitleRequest.Length >= sizeof(WCHAR)) + { + Length = min(Request->Data.GetTitleRequest.Length - sizeof(WCHAR), Console->Title.Length); + memcpy(Request->Data.GetTitleRequest.Title, Console->Title.Buffer, Length); + Request->Data.GetTitleRequest.Title[Length / sizeof(WCHAR)] = L'\0'; + } + + Request->Data.GetTitleRequest.Length = Console->Title.Length; + + ConioUnlockConsole(Console); + return STATUS_SUCCESS; +} + +/********************************************************************** + * HardwareStateProperty + * + * DESCRIPTION + * Set/Get the value of the HardwareState and switch + * between direct video buffer ouput and GDI windowed + * output. + * ARGUMENTS + * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE + * object. We use the same object to Request. + * NOTE + * ConsoleHwState has the correct size to be compatible + * with NT's, but values are not. + */ +static NTSTATUS FASTCALL +SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState) +{ + DPRINT1("Console Hardware State: %d\n", ConsoleHwState); + + if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) + ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) + { + if (Console->HardwareState != ConsoleHwState) + { + /* TODO: implement switching from full screen to windowed mode */ + /* TODO: or back; now simply store the hardware state */ + Console->HardwareState = ConsoleHwState; + } + + return STATUS_SUCCESS; + } + + return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ +} + +CSR_API(CsrHardwareStateProperty) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrHardwareStateProperty\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioLockConsole(ProcessData, + Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, + &Console, + GENERIC_READ); + if (! NT_SUCCESS(Status)) + { + DPRINT1("Failed to get console handle in SetConsoleHardwareState\n"); + return Status; + } + + switch (Request->Data.ConsoleHardwareStateRequest.SetGet) + { + case CONSOLE_HARDWARE_STATE_GET: + Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState; + break; + + case CONSOLE_HARDWARE_STATE_SET: + DPRINT("Setting console hardware state.\n"); + Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State); + break; + + default: + Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */ + break; + } + + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrGetConsoleWindow) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrGetConsoleWindow\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow; + ConioUnlockConsole(Console); + + return STATUS_SUCCESS; +} + +CSR_API(CsrSetConsoleIcon) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrSetConsoleIcon\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon) + ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrGetConsoleCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrGetConsoleCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetConsoleCodePage.CodePage = Console->CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; +} + +CSR_API(CsrSetConsoleCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrSetConsoleCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage)) + { + Console->CodePage = Request->Data.SetConsoleCodePage.CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; + } + + ConioUnlockConsole(Console); + return STATUS_INVALID_PARAMETER; +} + +CSR_API(CsrGetConsoleOutputCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrGetConsoleOutputCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; +} + +CSR_API(CsrSetConsoleOutputCodePage) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + DPRINT("CsrSetConsoleOutputCodePage\n"); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage)) + { + Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage; + ConioUnlockConsole(Console); + return STATUS_SUCCESS; + } + + ConioUnlockConsole(Console); + return STATUS_INVALID_PARAMETER; +} + +CSR_API(CsrGetProcessList) +{ + PDWORD Buffer; + PCSRSS_CONSOLE Console; + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + ULONG nItems = 0; + NTSTATUS Status; + + DPRINT("CsrGetProcessList\n"); + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Buffer = Request->Data.GetProcessListRequest.ProcessId; + if (!Win32CsrValidateBuffer(ProcessData, Buffer, Request->Data.GetProcessListRequest.nMaxIds, sizeof(DWORD))) + return STATUS_ACCESS_VIOLATION; + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds) + { + *Buffer++ = (DWORD)current->ProcessId; + } + } + + ConioUnlockConsole(Console); + + Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems; + return STATUS_SUCCESS; +} + +CSR_API(CsrGenerateCtrlEvent) +{ + PCSRSS_CONSOLE Console; + PCSRSS_PROCESS_DATA current; + PLIST_ENTRY current_entry; + DWORD Group; + NTSTATUS Status; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + Group = Request->Data.GenerateCtrlEvent.ProcessGroup; + Status = STATUS_INVALID_PARAMETER; + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + if (Group == 0 || current->ProcessGroup == Group) + { + ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current); + Status = STATUS_SUCCESS; + } + } + + ConioUnlockConsole(Console); + + return Status; +} + +CSR_API(CsrGetConsoleSelectionInfo) +{ + NTSTATUS Status; + PCSRSS_CONSOLE Console; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO)); + if (Console->Selection.dwFlags != 0) + Request->Data.GetConsoleSelectionInfo.Info = Console->Selection; + ConioUnlockConsole(Console); + } + return Status; +} + +/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/desktopbg.c b/subsystems/win32/csrss/win32csr/desktopbg.c index 7221f323df9..1853ab6cc21 100644 --- a/subsystems/win32/csrss/win32csr/desktopbg.c +++ b/subsystems/win32/csrss/win32csr/desktopbg.c @@ -49,71 +49,71 @@ DtbgWindowProc(HWND Wnd, switch (Msg) { - case WM_ERASEBKGND: - PaintDesktop((HDC)wParam); - return 1; + case WM_ERASEBKGND: + PaintDesktop((HDC)wParam); + return 1; - case WM_PAINT: - if (BeginPaint(Wnd, &PS)) - EndPaint(Wnd, &PS); - return 0; + case WM_PAINT: + if (BeginPaint(Wnd, &PS)) + EndPaint(Wnd, &PS); + return 0; - case WM_SETCURSOR: - return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW)); + case WM_SETCURSOR: + return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW)); - case WM_NCCREATE: - return (LRESULT)TRUE; + case WM_NCCREATE: + return (LRESULT)TRUE; - case WM_CREATE: - case WM_CLOSE: - return 0; + case WM_CREATE: + case WM_CLOSE: + return 0; - case WM_NOTIFY: + case WM_NOTIFY: + { + PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam; + + /* Use WM_NOTIFY for private messages since + * it can't be sent between processes! + */ + switch (nmh->hdr.code) { - PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam; + case PM_SHOW_DESKTOP: + { + LRESULT Result; - /* Use WM_NOTIFY for private messages since - * it can't be sent between processes! - */ - switch (nmh->hdr.code) - { - case PM_SHOW_DESKTOP: - { - LRESULT Result; + Result = !SetWindowPos(Wnd, NULL, 0, 0, + nmh->ShowDesktop.Width, + nmh->ShowDesktop.Height, + SWP_NOACTIVATE | SWP_NOZORDER | + SWP_SHOWWINDOW); - Result = !SetWindowPos(Wnd, NULL, 0, 0, - nmh->ShowDesktop.Width, - nmh->ShowDesktop.Height, - SWP_NOACTIVATE | SWP_NOZORDER | - SWP_SHOWWINDOW); + UpdateWindow(Wnd); + VisibleDesktopWindow = Wnd; + return Result; + } - UpdateWindow(Wnd); - VisibleDesktopWindow = Wnd; - return Result; - } + case PM_HIDE_DESKTOP: + { + LRESULT Result; - case PM_HIDE_DESKTOP: - { - LRESULT Result; + Result = !SetWindowPos(Wnd, NULL, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOZORDER | + SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); - Result = !SetWindowPos(Wnd, NULL, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOZORDER | - SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); - - UpdateWindow(Wnd); - VisibleDesktopWindow = NULL; - return Result; - } - - default: - DPRINT("Unknown notification code 0x%x sent to the desktop window!\n", - nmh->hdr.code); - return 0; - } + UpdateWindow(Wnd); + VisibleDesktopWindow = NULL; + return Result; } default: - return DefWindowProcW(Wnd, Msg, wParam, lParam); + DPRINT("Unknown notification code 0x%x sent to the desktop window!\n", + nmh->hdr.code); + return 0; + } + } + + default: + return DefWindowProcW(Wnd, Msg, wParam, lParam); } return 0; @@ -309,7 +309,7 @@ FASTCALL DtbgIsDesktopVisible(VOID) { if (VisibleDesktopWindow != NULL && - !IsWindowVisible(VisibleDesktopWindow)) + !IsWindowVisible(VisibleDesktopWindow)) { VisibleDesktopWindow = NULL; } diff --git a/subsystems/win32/csrss/include/desktopbg.h b/subsystems/win32/csrss/win32csr/desktopbg.h similarity index 100% rename from subsystems/win32/csrss/include/desktopbg.h rename to subsystems/win32/csrss/win32csr/desktopbg.h diff --git a/subsystems/win32/csrss/win32csr/dllmain.c b/subsystems/win32/csrss/win32csr/dllmain.c index f8332a7ea76..081788394bb 100644 --- a/subsystems/win32/csrss/win32csr/dllmain.c +++ b/subsystems/win32/csrss/win32csr/dllmain.c @@ -13,7 +13,6 @@ /* Not defined in any header file */ extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); -extern VOID WINAPI PrivateCsrssInitialized(); extern VOID WINAPI InitializeAppSwitchHook(); /* GLOBALS *******************************************************************/ @@ -23,7 +22,13 @@ HINSTANCE Win32CsrDllHandle = NULL; static CSRSS_EXPORTED_FUNCS CsrExports; static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = - { +{ + CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle), + CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle), + CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), + CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), + CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), + CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle), CSRSS_DEFINE_API(WRITE_CONSOLE, CsrWriteConsole), CSRSS_DEFINE_API(READ_CONSOLE, CsrReadConsole), CSRSS_DEFINE_API(ALLOC_CONSOLE, CsrAllocConsole), @@ -75,135 +80,93 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength), CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent), CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize), + CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo), + CSRSS_DEFINE_API(GET_COMMAND_HISTORY_LENGTH, CsrGetCommandHistoryLength), + CSRSS_DEFINE_API(GET_COMMAND_HISTORY, CsrGetCommandHistory), + CSRSS_DEFINE_API(EXPUNGE_COMMAND_HISTORY, CsrExpungeCommandHistory), + CSRSS_DEFINE_API(SET_HISTORY_NUMBER_COMMANDS, CsrSetHistoryNumberCommands), + CSRSS_DEFINE_API(GET_HISTORY_INFO, CsrGetHistoryInfo), + CSRSS_DEFINE_API(SET_HISTORY_INFO, CsrSetHistoryInfo), { 0, 0, NULL } - }; - -static CSRSS_OBJECT_DEFINITION Win32CsrObjectDefinitions[] = - { - { CONIO_CONSOLE_MAGIC, ConioDeleteConsole }, - { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer }, - { 0, NULL } - }; +}; /* FUNCTIONS *****************************************************************/ BOOL WINAPI DllMain(HANDLE hDll, - DWORD dwReason, - LPVOID lpReserved) + DWORD dwReason, + LPVOID lpReserved) { - if (DLL_PROCESS_ATTACH == dwReason) + if (DLL_PROCESS_ATTACH == dwReason) { - Win32CsrDllHandle = hDll; - InitializeAppSwitchHook(); + Win32CsrDllHandle = hDll; + InitializeAppSwitchHook(); } - return TRUE; + return TRUE; } -NTSTATUS FASTCALL -Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, - PHANDLE Handle, - Object_t *Object, - DWORD Access, - BOOL Inheritable) +/* Ensure that a captured buffer is safe to access */ +BOOL FASTCALL +Win32CsrValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, PVOID Buffer, + SIZE_T NumElements, SIZE_T ElementSize) { - return (CsrExports.CsrInsertObjectProc)(ProcessData, Handle, Object, Access, Inheritable); -} - -NTSTATUS FASTCALL -Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access) -{ - return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access); -} - -NTSTATUS FASTCALL -Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Handle, - Object_t **Object, - DWORD Access, - LONG Type) -{ - NTSTATUS Status; - - Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, Access); - if (! NT_SUCCESS(Status)) + /* Check that the following conditions are true: + * 1. The start of the buffer is somewhere within the process's + * shared memory section view. + * 2. The remaining space in the view is at least as large as the buffer. + * (NB: Please don't try to "optimize" this by using multiplication + * instead of division; remember that 2147483648 * 2 = 0.) + * 3. The buffer is DWORD-aligned. + */ + ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->CsrSectionViewBase; + if (Offset >= ProcessData->CsrSectionViewSize + || NumElements > (ProcessData->CsrSectionViewSize - Offset) / ElementSize + || (Offset & (sizeof(DWORD) - 1)) != 0) { - return Status; + DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n", + Buffer, NumElements, ElementSize, + ProcessData->CsrSectionViewBase, ProcessData->CsrSectionViewSize); + return FALSE; } - - if ((*Object)->Type != Type) - { - (CsrExports.CsrReleaseObjectByPointerProc)(*Object); - return STATUS_INVALID_HANDLE; - } - - EnterCriticalSection(&((*Object)->Lock)); - - return STATUS_SUCCESS; -} - -VOID FASTCALL -Win32CsrUnlockObject(Object_t *Object) -{ - LeaveCriticalSection(&(Object->Lock)); - (CsrExports.CsrReleaseObjectByPointerProc)(Object); -} - -NTSTATUS FASTCALL -Win32CsrReleaseObjectByPointer(Object_t *Object) -{ - return (CsrExports.CsrReleaseObjectByPointerProc)(Object); -} - -NTSTATUS FASTCALL -Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, - HANDLE Object) -{ - return (CsrExports.CsrReleaseObjectProc)(ProcessData, Object); + return TRUE; } NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context) { - return (CsrExports.CsrEnumProcessesProc)(EnumProc, Context); + return (CsrExports.CsrEnumProcessesProc)(EnumProc, Context); } static BOOL WINAPI Win32CsrInitComplete(void) { - PrivateCsrssInitialized(); - - return TRUE; + return TRUE; } BOOL WINAPI Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions, - PCSRSS_OBJECT_DEFINITION *ObjectDefinitions, - CSRPLUGIN_INIT_COMPLETE_PROC *InitComplete, - CSRPLUGIN_HARDERROR_PROC *HardError, + PCSRPLUGIN_SERVER_PROCS ServerProcs, PCSRSS_EXPORTED_FUNCS Exports, HANDLE CsrssApiHeap) { - NTSTATUS Status; - CsrExports = *Exports; - Win32CsrApiHeap = CsrssApiHeap; + NTSTATUS Status; + CsrExports = *Exports; + Win32CsrApiHeap = CsrssApiHeap; - Status = NtUserInitialize(0 ,NULL, NULL); + Status = NtUserInitialize(0, NULL, NULL); - PrivateCsrssManualGuiCheck(0); - CsrInitConsoleSupport(); + PrivateCsrssManualGuiCheck(0); + CsrInitConsoleSupport(); - *ApiDefinitions = Win32CsrApiDefinitions; - *ObjectDefinitions = Win32CsrObjectDefinitions; - *InitComplete = Win32CsrInitComplete; - *HardError = Win32CsrHardError; + *ApiDefinitions = Win32CsrApiDefinitions; + ServerProcs->InitCompleteProc = Win32CsrInitComplete; + ServerProcs->HardErrorProc = Win32CsrHardError; + ServerProcs->ProcessInheritProc = Win32CsrDuplicateHandleTable; + ServerProcs->ProcessDeletedProc = Win32CsrReleaseConsole; - return TRUE; + return TRUE; } /* EOF */ diff --git a/subsystems/win32/csrss/win32csr/exitros.c b/subsystems/win32/csrss/win32csr/exitros.c index 5b1195ec727..984b44a86a3 100644 --- a/subsystems/win32/csrss/win32csr/exitros.c +++ b/subsystems/win32/csrss/win32csr/exitros.c @@ -18,61 +18,61 @@ static HANDLE LogonProcess = NULL; CSR_API(CsrRegisterLogonProcess) { - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); - if (Request->Data.RegisterLogonProcessRequest.Register) + if (Request->Data.RegisterLogonProcessRequest.Register) { - if (0 != LogonProcess) + if (0 != LogonProcess) { - return STATUS_LOGON_SESSION_EXISTS; + return STATUS_LOGON_SESSION_EXISTS; } - LogonProcess = Request->Data.RegisterLogonProcessRequest.ProcessId; + LogonProcess = Request->Data.RegisterLogonProcessRequest.ProcessId; } - else + else { - if (Request->Header.ClientId.UniqueProcess != LogonProcess) + if (Request->Header.ClientId.UniqueProcess != LogonProcess) { - DPRINT1("Current logon process 0x%x, can't deregister from process 0x%x\n", - LogonProcess, Request->Header.ClientId.UniqueProcess); - return STATUS_NOT_LOGON_PROCESS; + DPRINT1("Current logon process 0x%x, can't deregister from process 0x%x\n", + LogonProcess, Request->Header.ClientId.UniqueProcess); + return STATUS_NOT_LOGON_PROCESS; } - LogonProcess = 0; + LogonProcess = 0; } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } CSR_API(CsrSetLogonNotifyWindow) { - DWORD WindowCreator; + DWORD WindowCreator; - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - + sizeof(PORT_MESSAGE); - if (0 == GetWindowThreadProcessId(Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow, - &WindowCreator)) + if (0 == GetWindowThreadProcessId(Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow, + &WindowCreator)) { - DPRINT1("Can't get window creator\n"); - return STATUS_INVALID_HANDLE; + DPRINT1("Can't get window creator\n"); + return STATUS_INVALID_HANDLE; } - if (WindowCreator != (DWORD_PTR)LogonProcess) + if (WindowCreator != (DWORD_PTR)LogonProcess) { - DPRINT1("Trying to register window not created by winlogon as notify window\n"); - return STATUS_ACCESS_DENIED; + DPRINT1("Trying to register window not created by winlogon as notify window\n"); + return STATUS_ACCESS_DENIED; } - LogonNotifyWindow = Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow; + LogonNotifyWindow = Request->Data.SetLogonNotifyWindowRequest.LogonNotifyWindow; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } typedef struct tagSHUTDOWN_SETTINGS { - BOOL AutoEndTasks; - DWORD HungAppTimeout; - DWORD WaitToKillAppTimeout; + BOOL AutoEndTasks; + DWORD HungAppTimeout; + DWORD WaitToKillAppTimeout; } SHUTDOWN_SETTINGS, *PSHUTDOWN_SETTINGS; #define DEFAULT_AUTO_END_TASKS FALSE @@ -81,20 +81,20 @@ typedef struct tagSHUTDOWN_SETTINGS typedef struct tagNOTIFY_CONTEXT { - DWORD ProcessId; - UINT Msg; - WPARAM wParam; - LPARAM lParam; - HDESK Desktop; - DWORD StartTime; - DWORD QueryResult; - HWND Dlg; - DWORD EndNowResult; - BOOL ShowUI; - HANDLE UIThread; - HWND WndClient; - PSHUTDOWN_SETTINGS ShutdownSettings; - LPTHREAD_START_ROUTINE SendMessageProc; + DWORD ProcessId; + UINT Msg; + WPARAM wParam; + LPARAM lParam; + HDESK Desktop; + DWORD StartTime; + DWORD QueryResult; + HWND Dlg; + DWORD EndNowResult; + BOOL ShowUI; + HANDLE UIThread; + HWND WndClient; + PSHUTDOWN_SETTINGS ShutdownSettings; + LPTHREAD_START_ROUTINE SendMessageProc; } NOTIFY_CONTEXT, *PNOTIFY_CONTEXT; #define QUERY_RESULT_ABORT 0 @@ -106,30 +106,30 @@ typedef struct tagNOTIFY_CONTEXT static void FASTCALL UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext) { - DWORD Passed; + DWORD Passed; - Passed = GetTickCount() - NotifyContext->StartTime; - Passed -= NotifyContext->ShutdownSettings->HungAppTimeout; - if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed) + Passed = GetTickCount() - NotifyContext->StartTime; + Passed -= NotifyContext->ShutdownSettings->HungAppTimeout; + if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed) { - Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout; + Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout; } - SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0); + SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0); } static INT_PTR CALLBACK EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) { - INT_PTR Result; - PNOTIFY_CONTEXT NotifyContext; - HWND ProgressBar; - DWORD TitleLength; - int Len; - LPWSTR Title; + INT_PTR Result; + PNOTIFY_CONTEXT NotifyContext; + HWND ProgressBar; + DWORD TitleLength; + int Len; + LPWSTR Title; - switch(Msg) + switch(Msg) { - case WM_INITDIALOG: + case WM_INITDIALOG: NotifyContext = (PNOTIFY_CONTEXT) lParam; NotifyContext->EndNowResult = QUERY_RESULT_ABORT; SetWindowLongPtrW(Dlg, DWLP_USER, (LONG_PTR) lParam); @@ -138,13 +138,13 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) GetWindowTextLengthW(Dlg); Title = HeapAlloc(Win32CsrApiHeap, 0, (TitleLength + 1) * sizeof(WCHAR)); if (NULL != Title) - { + { Len = GetWindowTextW(Dlg, Title, TitleLength + 1); SendMessageW(NotifyContext->WndClient, WM_GETTEXT, TitleLength + 1 - Len, (LPARAM) (Title + Len)); SetWindowTextW(Dlg, Title); HeapFree(Win32CsrApiHeap, 0, Title); - } + } ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS); SendMessageW(ProgressBar, PBM_SETRANGE32, 0, NotifyContext->ShutdownSettings->WaitToKillAppTimeout / 2); @@ -153,33 +153,33 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) Result = FALSE; break; - case WM_TIMER: + case WM_TIMER: NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER); ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS); UpdateProgressBar(ProgressBar, NotifyContext); Result = TRUE; break; - case WM_COMMAND: + case WM_COMMAND: if (BN_CLICKED == HIWORD(wParam) && IDC_END_NOW == LOWORD(wParam)) - { + { NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER); NotifyContext->EndNowResult = QUERY_RESULT_FORCE; SendMessageW(Dlg, WM_CLOSE, 0, 0); Result = TRUE; - } + } else - { + { Result = FALSE; - } + } break; - case WM_CLOSE: + case WM_CLOSE: DestroyWindow(Dlg); Result = TRUE; break; - case WM_DESTROY: + case WM_DESTROY: NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER); NotifyContext->Dlg = NULL; KillTimer(Dlg, 0); @@ -187,278 +187,278 @@ EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam) Result = TRUE; break; - default: + default: Result = FALSE; break; } - return Result; + return Result; } typedef void (WINAPI *INITCOMMONCONTROLS_PROC)(void); -static void FASTCALL +static void CallInitCommonControls() { - static BOOL Initialized = FALSE; - HMODULE Lib; - INITCOMMONCONTROLS_PROC InitProc; + static BOOL Initialized = FALSE; + HMODULE Lib; + INITCOMMONCONTROLS_PROC InitProc; - if (Initialized) + if (Initialized) { - return; + return; } - Lib = LoadLibraryW(L"COMCTL32.DLL"); - if (NULL == Lib) + Lib = LoadLibraryW(L"COMCTL32.DLL"); + if (NULL == Lib) { - return; + return; } - InitProc = (INITCOMMONCONTROLS_PROC) GetProcAddress(Lib, "InitCommonControls"); - if (NULL == InitProc) + InitProc = (INITCOMMONCONTROLS_PROC) GetProcAddress(Lib, "InitCommonControls"); + if (NULL == InitProc) { - return; + return; } - (*InitProc)(); + (*InitProc)(); - Initialized = TRUE; + Initialized = TRUE; } static DWORD WINAPI EndNowThreadProc(LPVOID Parameter) { - PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) Parameter; - MSG Msg; + PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) Parameter; + MSG Msg; - SetThreadDesktop(NotifyContext->Desktop); - SwitchDesktop(NotifyContext->Desktop); - CallInitCommonControls(); - NotifyContext->Dlg = CreateDialogParam(GetModuleHandleW(L"win32csr"), - MAKEINTRESOURCE(IDD_END_NOW), NULL, - EndNowDlgProc, (LPARAM) NotifyContext); - if (NULL == NotifyContext->Dlg) + SetThreadDesktop(NotifyContext->Desktop); + SwitchDesktop(NotifyContext->Desktop); + CallInitCommonControls(); + NotifyContext->Dlg = CreateDialogParam(GetModuleHandleW(L"win32csr"), + MAKEINTRESOURCE(IDD_END_NOW), NULL, + EndNowDlgProc, (LPARAM) NotifyContext); + if (NULL == NotifyContext->Dlg) { - return 0; + return 0; } - ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL); + ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL); - while (GetMessageW(&Msg, NULL, 0, 0)) + while (GetMessageW(&Msg, NULL, 0, 0)) { - if (! IsDialogMessage(NotifyContext->Dlg, &Msg)) + if (! IsDialogMessage(NotifyContext->Dlg, &Msg)) { - TranslateMessage(&Msg); - DispatchMessageW(&Msg); + TranslateMessage(&Msg); + DispatchMessageW(&Msg); } } - return Msg.wParam; + return Msg.wParam; } typedef struct tagMESSAGE_CONTEXT { - HWND Wnd; - UINT Msg; - WPARAM wParam; - LPARAM lParam; - DWORD Timeout; + HWND Wnd; + UINT Msg; + WPARAM wParam; + LPARAM lParam; + DWORD Timeout; } MESSAGE_CONTEXT, *PMESSAGE_CONTEXT; static DWORD WINAPI SendQueryEndSession(LPVOID Parameter) { - PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; - DWORD_PTR Result; + PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; + DWORD_PTR Result; - if (SendMessageTimeoutW(Context->Wnd, WM_QUERYENDSESSION, Context->wParam, - Context->lParam, SMTO_NORMAL, Context->Timeout, - &Result)) + if (SendMessageTimeoutW(Context->Wnd, WM_QUERYENDSESSION, Context->wParam, + Context->lParam, SMTO_NORMAL, Context->Timeout, + &Result)) { - return Result ? QUERY_RESULT_CONTINUE : QUERY_RESULT_ABORT; + return Result ? QUERY_RESULT_CONTINUE : QUERY_RESULT_ABORT; } - return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; + return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; } static DWORD WINAPI SendEndSession(LPVOID Parameter) { - PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; - DWORD_PTR Result; + PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter; + DWORD_PTR Result; - if (Context->wParam) + if (Context->wParam) { - if (SendMessageTimeoutW(Context->Wnd, WM_ENDSESSION, Context->wParam, - Context->lParam, SMTO_NORMAL, Context->Timeout, - &Result)) + if (SendMessageTimeoutW(Context->Wnd, WM_ENDSESSION, Context->wParam, + Context->lParam, SMTO_NORMAL, Context->Timeout, + &Result)) { - return QUERY_RESULT_CONTINUE; + return QUERY_RESULT_CONTINUE; } - return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; + return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR; } - else + else { - SendMessage(Context->Wnd, WM_ENDSESSION, Context->wParam, - Context->lParam); - return QUERY_RESULT_CONTINUE; + SendMessage(Context->Wnd, WM_ENDSESSION, Context->wParam, + Context->lParam); + return QUERY_RESULT_CONTINUE; } } static BOOL CALLBACK NotifyTopLevelEnum(HWND Wnd, LPARAM lParam) { - PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) lParam; - MESSAGE_CONTEXT MessageContext; - DWORD Now, Passed; - DWORD Timeout, WaitStatus; - DWORD ProcessId; - HANDLE MessageThread; - HANDLE Threads[2]; + PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) lParam; + MESSAGE_CONTEXT MessageContext; + DWORD Now, Passed; + DWORD Timeout, WaitStatus; + DWORD ProcessId; + HANDLE MessageThread; + HANDLE Threads[2]; - if (0 == GetWindowThreadProcessId(Wnd, &ProcessId)) + if (0 == GetWindowThreadProcessId(Wnd, &ProcessId)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; - return FALSE; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; + return FALSE; } - if (ProcessId == NotifyContext->ProcessId) + if (ProcessId == NotifyContext->ProcessId) { - Now = GetTickCount(); - if (0 == NotifyContext->StartTime) + Now = GetTickCount(); + if (0 == NotifyContext->StartTime) { - NotifyContext->StartTime = Now; + NotifyContext->StartTime = Now; } - /* Note: Passed is computed correctly even when GetTickCount() wraps due - to unsigned arithmetic */ - Passed = Now - NotifyContext->StartTime; - MessageContext.Wnd = Wnd; - MessageContext.Msg = NotifyContext->Msg; - MessageContext.wParam = NotifyContext->wParam; - MessageContext.lParam = NotifyContext->lParam; - MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; - if (! NotifyContext->ShutdownSettings->AutoEndTasks) + /* Note: Passed is computed correctly even when GetTickCount() wraps due + to unsigned arithmetic */ + Passed = Now - NotifyContext->StartTime; + MessageContext.Wnd = Wnd; + MessageContext.Msg = NotifyContext->Msg; + MessageContext.wParam = NotifyContext->wParam; + MessageContext.lParam = NotifyContext->lParam; + MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; + if (! NotifyContext->ShutdownSettings->AutoEndTasks) { - MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout; + MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout; } - if (Passed < MessageContext.Timeout) + if (Passed < MessageContext.Timeout) { - MessageContext.Timeout -= Passed; - MessageThread = CreateThread(NULL, 0, NotifyContext->SendMessageProc, - (LPVOID) &MessageContext, 0, NULL); - if (NULL == MessageThread) + MessageContext.Timeout -= Passed; + MessageThread = CreateThread(NULL, 0, NotifyContext->SendMessageProc, + (LPVOID) &MessageContext, 0, NULL); + if (NULL == MessageThread) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; - return FALSE; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; + return FALSE; } - Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; - if (Passed < Timeout) + Timeout = NotifyContext->ShutdownSettings->HungAppTimeout; + if (Passed < Timeout) { - Timeout -= Passed; - WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE); + Timeout -= Passed; + WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE); } - else + else { - WaitStatus = WAIT_TIMEOUT; + WaitStatus = WAIT_TIMEOUT; } - if (WAIT_TIMEOUT == WaitStatus) + if (WAIT_TIMEOUT == WaitStatus) { - NotifyContext->WndClient = Wnd; - if (NULL == NotifyContext->UIThread && NotifyContext->ShowUI) + NotifyContext->WndClient = Wnd; + if (NULL == NotifyContext->UIThread && NotifyContext->ShowUI) { - NotifyContext->UIThread = CreateThread(NULL, 0, - EndNowThreadProc, - (LPVOID) NotifyContext, - 0, NULL); + NotifyContext->UIThread = CreateThread(NULL, 0, + EndNowThreadProc, + (LPVOID) NotifyContext, + 0, NULL); } - Threads[0] = MessageThread; - Threads[1] = NotifyContext->UIThread; - WaitStatus = WaitForMultipleObjectsEx(NULL == NotifyContext->UIThread ? - 1 : 2, - Threads, FALSE, INFINITE, - FALSE); - if (WAIT_OBJECT_0 == WaitStatus) + Threads[0] = MessageThread; + Threads[1] = NotifyContext->UIThread; + WaitStatus = WaitForMultipleObjectsEx(NULL == NotifyContext->UIThread ? + 1 : 2, + Threads, FALSE, INFINITE, + FALSE); + if (WAIT_OBJECT_0 == WaitStatus) { - if (! GetExitCodeThread(MessageThread, &NotifyContext->QueryResult)) + if (! GetExitCodeThread(MessageThread, &NotifyContext->QueryResult)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } } - else if (WAIT_OBJECT_0 + 1 == WaitStatus) + else if (WAIT_OBJECT_0 + 1 == WaitStatus) { - if (! GetExitCodeThread(NotifyContext->UIThread, - &NotifyContext->QueryResult)) + if (! GetExitCodeThread(NotifyContext->UIThread, + &NotifyContext->QueryResult)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } } - else + else { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } - if (WAIT_OBJECT_0 != WaitStatus) + if (WAIT_OBJECT_0 != WaitStatus) { - TerminateThread(MessageThread, QUERY_RESULT_TIMEOUT); + TerminateThread(MessageThread, QUERY_RESULT_TIMEOUT); } } - else if (WAIT_OBJECT_0 == WaitStatus) + else if (WAIT_OBJECT_0 == WaitStatus) { - if (! GetExitCodeThread(MessageThread, - &NotifyContext->QueryResult)) + if (! GetExitCodeThread(MessageThread, + &NotifyContext->QueryResult)) { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } } - else + else { - NotifyContext->QueryResult = QUERY_RESULT_ERROR; + NotifyContext->QueryResult = QUERY_RESULT_ERROR; } - CloseHandle(MessageThread); + CloseHandle(MessageThread); } - else + else { - NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT; + NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT; } } - return QUERY_RESULT_CONTINUE == NotifyContext->QueryResult; + return QUERY_RESULT_CONTINUE == NotifyContext->QueryResult; } static BOOL CALLBACK NotifyDesktopEnum(LPWSTR DesktopName, LPARAM lParam) { - PNOTIFY_CONTEXT Context = (PNOTIFY_CONTEXT) lParam; + PNOTIFY_CONTEXT Context = (PNOTIFY_CONTEXT) lParam; - Context->Desktop = OpenDesktopW(DesktopName, 0, FALSE, - DESKTOP_ENUMERATE | DESKTOP_SWITCHDESKTOP); - if (NULL == Context->Desktop) + Context->Desktop = OpenDesktopW(DesktopName, 0, FALSE, + DESKTOP_ENUMERATE | DESKTOP_SWITCHDESKTOP); + if (NULL == Context->Desktop) { - DPRINT1("OpenDesktop failed with error %d\n", GetLastError()); - Context->QueryResult = QUERY_RESULT_ERROR; - return FALSE; + DPRINT1("OpenDesktop failed with error %d\n", GetLastError()); + Context->QueryResult = QUERY_RESULT_ERROR; + return FALSE; } - EnumDesktopWindows(Context->Desktop, NotifyTopLevelEnum, lParam); + EnumDesktopWindows(Context->Desktop, NotifyTopLevelEnum, lParam); - CloseDesktop(Context->Desktop); + CloseDesktop(Context->Desktop); - return QUERY_RESULT_CONTINUE == Context->QueryResult; + return QUERY_RESULT_CONTINUE == Context->QueryResult; } static BOOL FASTCALL NotifyTopLevelWindows(PNOTIFY_CONTEXT Context) { - HWINSTA WindowStation; + HWINSTA WindowStation; - WindowStation = GetProcessWindowStation(); - if (NULL == WindowStation) + WindowStation = GetProcessWindowStation(); + if (NULL == WindowStation) { - DPRINT1("GetProcessWindowStation failed with error %d\n", GetLastError()); - return TRUE; + DPRINT1("GetProcessWindowStation failed with error %d\n", GetLastError()); + return TRUE; } - EnumDesktopsW(WindowStation, NotifyDesktopEnum, (LPARAM) Context); + EnumDesktopsW(WindowStation, NotifyDesktopEnum, (LPARAM) Context); - return TRUE; + return TRUE; } static BOOL FASTCALL @@ -466,476 +466,476 @@ NotifyAndTerminateProcess(PCSRSS_PROCESS_DATA ProcessData, PSHUTDOWN_SETTINGS ShutdownSettings, UINT Flags) { - NOTIFY_CONTEXT Context; - HANDLE Process; - DWORD QueryResult = QUERY_RESULT_CONTINUE; + NOTIFY_CONTEXT Context; + HANDLE Process; + DWORD QueryResult = QUERY_RESULT_CONTINUE; - Context.QueryResult = QUERY_RESULT_CONTINUE; + Context.QueryResult = QUERY_RESULT_CONTINUE; - if (0 == (Flags & EWX_FORCE)) + if (0 == (Flags & EWX_FORCE)) { - if (NULL != ProcessData->Console) + if (NULL != ProcessData->Console) { - ConioConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData, - ShutdownSettings->WaitToKillAppTimeout); + ConioConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData, + ShutdownSettings->WaitToKillAppTimeout); } - else + else { - Context.ProcessId = (DWORD_PTR) ProcessData->ProcessId; - Context.wParam = 0; - Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? - ENDSESSION_LOGOFF : 0); - Context.StartTime = 0; - Context.UIThread = NULL; - Context.ShowUI = DtbgIsDesktopVisible(); - Context.Dlg = NULL; - Context.ShutdownSettings = ShutdownSettings; - Context.SendMessageProc = SendQueryEndSession; + Context.ProcessId = (DWORD_PTR) ProcessData->ProcessId; + Context.wParam = 0; + Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? + ENDSESSION_LOGOFF : 0); + Context.StartTime = 0; + Context.UIThread = NULL; + Context.ShowUI = DtbgIsDesktopVisible(); + Context.Dlg = NULL; + Context.ShutdownSettings = ShutdownSettings; + Context.SendMessageProc = SendQueryEndSession; - NotifyTopLevelWindows(&Context); + NotifyTopLevelWindows(&Context); - Context.wParam = (QUERY_RESULT_ABORT != Context.QueryResult); - Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? - ENDSESSION_LOGOFF : 0); - Context.SendMessageProc = SendEndSession; - Context.ShowUI = DtbgIsDesktopVisible() && - (QUERY_RESULT_ABORT != Context.QueryResult); - QueryResult = Context.QueryResult; - Context.QueryResult = QUERY_RESULT_CONTINUE; + Context.wParam = (QUERY_RESULT_ABORT != Context.QueryResult); + Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ? + ENDSESSION_LOGOFF : 0); + Context.SendMessageProc = SendEndSession; + Context.ShowUI = DtbgIsDesktopVisible() && + (QUERY_RESULT_ABORT != Context.QueryResult); + QueryResult = Context.QueryResult; + Context.QueryResult = QUERY_RESULT_CONTINUE; - NotifyTopLevelWindows(&Context); + NotifyTopLevelWindows(&Context); - if (NULL != Context.UIThread) + if (NULL != Context.UIThread) { - if (NULL != Context.Dlg) + if (NULL != Context.Dlg) { - SendMessageW(Context.Dlg, WM_CLOSE, 0, 0); + SendMessageW(Context.Dlg, WM_CLOSE, 0, 0); } - else + else { - TerminateThread(Context.UIThread, QUERY_RESULT_ERROR); + TerminateThread(Context.UIThread, QUERY_RESULT_ERROR); } - CloseHandle(Context.UIThread); + CloseHandle(Context.UIThread); } } - if (QUERY_RESULT_ABORT == QueryResult) + if (QUERY_RESULT_ABORT == QueryResult) { - return FALSE; + return FALSE; } } - /* Terminate this process */ - Process = OpenProcess(PROCESS_TERMINATE, FALSE, - (DWORD_PTR) ProcessData->ProcessId); - if (NULL == Process) + /* Terminate this process */ + Process = OpenProcess(PROCESS_TERMINATE, FALSE, + (DWORD_PTR) ProcessData->ProcessId); + if (NULL == Process) { - DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, - GetLastError()); - return TRUE; + DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, + GetLastError()); + return TRUE; } - TerminateProcess(Process, 0); - CloseHandle(Process); + TerminateProcess(Process, 0); + CloseHandle(Process); - return TRUE; + return TRUE; } typedef struct tagPROCESS_ENUM_CONTEXT { - UINT ProcessCount; - PCSRSS_PROCESS_DATA *ProcessData; - TOKEN_ORIGIN TokenOrigin; - DWORD ShellProcess; - DWORD CsrssProcess; + UINT ProcessCount; + PCSRSS_PROCESS_DATA *ProcessData; + TOKEN_ORIGIN TokenOrigin; + DWORD ShellProcess; + DWORD CsrssProcess; } PROCESS_ENUM_CONTEXT, *PPROCESS_ENUM_CONTEXT; static NTSTATUS WINAPI ExitReactosProcessEnum(PCSRSS_PROCESS_DATA ProcessData, PVOID Data) { - HANDLE Process; - HANDLE Token; - TOKEN_ORIGIN Origin; - DWORD ReturnLength; - PPROCESS_ENUM_CONTEXT Context = (PPROCESS_ENUM_CONTEXT) Data; - PCSRSS_PROCESS_DATA *NewData; + HANDLE Process; + HANDLE Token; + TOKEN_ORIGIN Origin; + DWORD ReturnLength; + PPROCESS_ENUM_CONTEXT Context = (PPROCESS_ENUM_CONTEXT) Data; + PCSRSS_PROCESS_DATA *NewData; - /* Do not kill winlogon or csrss */ - if ((DWORD_PTR) ProcessData->ProcessId == Context->CsrssProcess || - ProcessData->ProcessId == LogonProcess) + /* Do not kill winlogon or csrss */ + if ((DWORD_PTR) ProcessData->ProcessId == Context->CsrssProcess || + ProcessData->ProcessId == LogonProcess) { - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - /* Get the login session of this process */ - Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, - (DWORD_PTR) ProcessData->ProcessId); - if (NULL == Process) + /* Get the login session of this process */ + Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, + (DWORD_PTR) ProcessData->ProcessId); + if (NULL == Process) { - DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, - GetLastError()); - return STATUS_UNSUCCESSFUL; + DPRINT1("Unable to open process %d, error %d\n", ProcessData->ProcessId, + GetLastError()); + return STATUS_UNSUCCESSFUL; } - if (! OpenProcessToken(Process, TOKEN_QUERY, &Token)) + if (! OpenProcessToken(Process, TOKEN_QUERY, &Token)) { - DPRINT1("Unable to open token for process %d, error %d\n", - ProcessData->ProcessId, GetLastError()); - CloseHandle(Process); - return STATUS_UNSUCCESSFUL; + DPRINT1("Unable to open token for process %d, error %d\n", + ProcessData->ProcessId, GetLastError()); + CloseHandle(Process); + return STATUS_UNSUCCESSFUL; } - CloseHandle(Process); + CloseHandle(Process); - if (! GetTokenInformation(Token, TokenOrigin, &Origin, - sizeof(TOKEN_ORIGIN), &ReturnLength)) + if (! GetTokenInformation(Token, TokenOrigin, &Origin, + sizeof(TOKEN_ORIGIN), &ReturnLength)) { - DPRINT1("GetTokenInformation failed for process %d with error %d\n", - ProcessData->ProcessId, GetLastError()); - CloseHandle(Token); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed for process %d with error %d\n", + ProcessData->ProcessId, GetLastError()); + CloseHandle(Token); + return STATUS_UNSUCCESSFUL; } - CloseHandle(Token); + CloseHandle(Token); - /* This process will be killed if it's in the correct logon session */ - if (RtlEqualLuid(&(Context->TokenOrigin.OriginatingLogonSession), - &(Origin.OriginatingLogonSession))) + /* This process will be killed if it's in the correct logon session */ + if (RtlEqualLuid(&(Context->TokenOrigin.OriginatingLogonSession), + &(Origin.OriginatingLogonSession))) { - /* Kill the shell process last */ - if ((DWORD_PTR) ProcessData->ProcessId == Context->ShellProcess) + /* Kill the shell process last */ + if ((DWORD_PTR) ProcessData->ProcessId == Context->ShellProcess) { - ProcessData->ShutdownLevel = 0; + ProcessData->ShutdownLevel = 0; } - NewData = HeapAlloc(Win32CsrApiHeap, 0, (Context->ProcessCount + 1) - * sizeof(PCSRSS_PROCESS_DATA)); - if (NULL == NewData) + NewData = HeapAlloc(Win32CsrApiHeap, 0, (Context->ProcessCount + 1) + * sizeof(PCSRSS_PROCESS_DATA)); + if (NULL == NewData) { - return STATUS_NO_MEMORY; + return STATUS_NO_MEMORY; } - if (0 != Context->ProcessCount) + if (0 != Context->ProcessCount) { - memcpy(NewData, Context->ProcessData, - Context->ProcessCount * sizeof(PCSRSS_PROCESS_DATA)); - HeapFree(Win32CsrApiHeap, 0, Context->ProcessData); + memcpy(NewData, Context->ProcessData, + Context->ProcessCount * sizeof(PCSRSS_PROCESS_DATA)); + HeapFree(Win32CsrApiHeap, 0, Context->ProcessData); } - Context->ProcessData = NewData; - Context->ProcessData[Context->ProcessCount] = ProcessData; - Context->ProcessCount++; + Context->ProcessData = NewData; + Context->ProcessData[Context->ProcessCount] = ProcessData; + Context->ProcessCount++; } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } static int ProcessDataCompare(const void *Elem1, const void *Elem2) { - const PCSRSS_PROCESS_DATA *ProcessData1 = (PCSRSS_PROCESS_DATA *) Elem1; - const PCSRSS_PROCESS_DATA *ProcessData2 = (PCSRSS_PROCESS_DATA *) Elem2; + const PCSRSS_PROCESS_DATA *ProcessData1 = (PCSRSS_PROCESS_DATA *) Elem1; + const PCSRSS_PROCESS_DATA *ProcessData2 = (PCSRSS_PROCESS_DATA *) Elem2; - if ((*ProcessData1)->ShutdownLevel < (*ProcessData2)->ShutdownLevel) + if ((*ProcessData1)->ShutdownLevel < (*ProcessData2)->ShutdownLevel) { - return +1; + return +1; } - else if ((*ProcessData2)->ShutdownLevel < (*ProcessData1)->ShutdownLevel) + else if ((*ProcessData2)->ShutdownLevel < (*ProcessData1)->ShutdownLevel) { - return -1; + return -1; } - else if ((*ProcessData1)->ProcessId < (*ProcessData2)->ProcessId) + else if ((*ProcessData1)->ProcessId < (*ProcessData2)->ProcessId) { - return +1; + return +1; } - else if ((*ProcessData2)->ProcessId < (*ProcessData1)->ProcessId) + else if ((*ProcessData2)->ProcessId < (*ProcessData1)->ProcessId) { - return -1; + return -1; } - return 0; + return 0; } static DWORD FASTCALL GetShutdownSetting(HKEY DesktopKey, LPCWSTR ValueName, DWORD DefaultValue) { - BYTE ValueBuffer[16]; - LONG ErrCode; - DWORD Type; - DWORD ValueSize; - UNICODE_STRING StringValue; - ULONG Value; + BYTE ValueBuffer[16]; + LONG ErrCode; + DWORD Type; + DWORD ValueSize; + UNICODE_STRING StringValue; + ULONG Value; - ValueSize = sizeof(ValueBuffer); - ErrCode = RegQueryValueExW(DesktopKey, ValueName, NULL, &Type, ValueBuffer, - &ValueSize); - if (ERROR_SUCCESS != ErrCode) + ValueSize = sizeof(ValueBuffer); + ErrCode = RegQueryValueExW(DesktopKey, ValueName, NULL, &Type, ValueBuffer, + &ValueSize); + if (ERROR_SUCCESS != ErrCode) { - DPRINT("GetShutdownSetting for %S failed with error code %ld\n", - ValueName, ErrCode); - return DefaultValue; + DPRINT("GetShutdownSetting for %S failed with error code %ld\n", + ValueName, ErrCode); + return DefaultValue; } - if (REG_SZ == Type) + if (REG_SZ == Type) { - RtlInitUnicodeString(&StringValue, (LPCWSTR) ValueBuffer); - if (! NT_SUCCESS(RtlUnicodeStringToInteger(&StringValue, 10, &Value))) + RtlInitUnicodeString(&StringValue, (LPCWSTR) ValueBuffer); + if (! NT_SUCCESS(RtlUnicodeStringToInteger(&StringValue, 10, &Value))) { - DPRINT1("Unable to convert value %S for setting %S\n", - StringValue.Buffer, ValueName); - return DefaultValue; + DPRINT1("Unable to convert value %S for setting %S\n", + StringValue.Buffer, ValueName); + return DefaultValue; } - return (DWORD) Value; + return (DWORD) Value; } - else if (REG_DWORD == Type) + else if (REG_DWORD == Type) { - return *((DWORD *) ValueBuffer); + return *((DWORD *) ValueBuffer); } - DPRINT1("Unexpected registry type %d for setting %S\n", Type, ValueName); - return DefaultValue; + DPRINT1("Unexpected registry type %d for setting %S\n", Type, ValueName); + return DefaultValue; } static void FASTCALL LoadShutdownSettings(PSID Sid, PSHUTDOWN_SETTINGS ShutdownSettings) { - static WCHAR Subkey[] = L"\\Control Panel\\Desktop"; - LPWSTR StringSid; - WCHAR InitialKeyName[128]; - LPWSTR KeyName; - HKEY DesktopKey; - LONG ErrCode; + static WCHAR Subkey[] = L"\\Control Panel\\Desktop"; + LPWSTR StringSid; + WCHAR InitialKeyName[128]; + LPWSTR KeyName; + HKEY DesktopKey; + LONG ErrCode; - ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS; - ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT; - ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT; + ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS; + ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT; + ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT; - if (! ConvertSidToStringSidW(Sid, &StringSid)) + if (! ConvertSidToStringSidW(Sid, &StringSid)) { - DPRINT1("ConvertSidToStringSid failed with error %d, using default shutdown settings\n", - GetLastError()); - return; + DPRINT1("ConvertSidToStringSid failed with error %d, using default shutdown settings\n", + GetLastError()); + return; } - if (wcslen(StringSid) + wcslen(Subkey) + 1 <= - sizeof(InitialKeyName) / sizeof(WCHAR)) + if (wcslen(StringSid) + wcslen(Subkey) + 1 <= + sizeof(InitialKeyName) / sizeof(WCHAR)) { - KeyName = InitialKeyName; + KeyName = InitialKeyName; } - else + else { - KeyName = HeapAlloc(Win32CsrApiHeap, 0, - (wcslen(StringSid) + wcslen(Subkey) + 1) * - sizeof(WCHAR)); - if (NULL == KeyName) + KeyName = HeapAlloc(Win32CsrApiHeap, 0, + (wcslen(StringSid) + wcslen(Subkey) + 1) * + sizeof(WCHAR)); + if (NULL == KeyName) { - DPRINT1("Failed to allocate memory, using default shutdown settings\n"); - LocalFree(StringSid); - return; + DPRINT1("Failed to allocate memory, using default shutdown settings\n"); + LocalFree(StringSid); + return; } } - wcscat(wcscpy(KeyName, StringSid), Subkey); - LocalFree(StringSid); + wcscat(wcscpy(KeyName, StringSid), Subkey); + LocalFree(StringSid); - ErrCode = RegOpenKeyExW(HKEY_USERS, KeyName, 0, KEY_QUERY_VALUE, &DesktopKey); - if (KeyName != InitialKeyName) + ErrCode = RegOpenKeyExW(HKEY_USERS, KeyName, 0, KEY_QUERY_VALUE, &DesktopKey); + if (KeyName != InitialKeyName) { - HeapFree(Win32CsrApiHeap, 0, KeyName); + HeapFree(Win32CsrApiHeap, 0, KeyName); } - if (ERROR_SUCCESS != ErrCode) + if (ERROR_SUCCESS != ErrCode) { - DPRINT1("RegOpenKeyEx failed with error %ld, using default shutdown settings\n", ErrCode); - return; + DPRINT1("RegOpenKeyEx failed with error %ld, using default shutdown settings\n", ErrCode); + return; } - ShutdownSettings->AutoEndTasks = (BOOL) GetShutdownSetting(DesktopKey, L"AutoEndTasks", - (DWORD) DEFAULT_AUTO_END_TASKS); - ShutdownSettings->HungAppTimeout = GetShutdownSetting(DesktopKey, - L"HungAppTimeout", - DEFAULT_HUNG_APP_TIMEOUT); - ShutdownSettings->WaitToKillAppTimeout = GetShutdownSetting(DesktopKey, - L"WaitToKillAppTimeout", - DEFAULT_WAIT_TO_KILL_APP_TIMEOUT); + ShutdownSettings->AutoEndTasks = (BOOL) GetShutdownSetting(DesktopKey, L"AutoEndTasks", + (DWORD) DEFAULT_AUTO_END_TASKS); + ShutdownSettings->HungAppTimeout = GetShutdownSetting(DesktopKey, + L"HungAppTimeout", + DEFAULT_HUNG_APP_TIMEOUT); + ShutdownSettings->WaitToKillAppTimeout = GetShutdownSetting(DesktopKey, + L"WaitToKillAppTimeout", + DEFAULT_WAIT_TO_KILL_APP_TIMEOUT); - RegCloseKey(DesktopKey); + RegCloseKey(DesktopKey); } static NTSTATUS FASTCALL InternalExitReactos(DWORD ProcessId, DWORD ThreadId, UINT Flags) { - HANDLE CallerThread; - HANDLE CallerToken; - NTSTATUS Status; - PROCESS_ENUM_CONTEXT Context; - DWORD ReturnLength; - HWND ShellWnd; - UINT ProcessIndex; - char FixedUserInfo[64]; - TOKEN_USER *UserInfo; - SHUTDOWN_SETTINGS ShutdownSettings; + HANDLE CallerThread; + HANDLE CallerToken; + NTSTATUS Status; + PROCESS_ENUM_CONTEXT Context; + DWORD ReturnLength; + HWND ShellWnd; + UINT ProcessIndex; + char FixedUserInfo[64]; + TOKEN_USER *UserInfo; + SHUTDOWN_SETTINGS ShutdownSettings; - if (ProcessId != (DWORD_PTR) LogonProcess) + if (ProcessId != (DWORD_PTR) LogonProcess) { - DPRINT1("Internal ExitWindowsEx call not from winlogon\n"); - return STATUS_ACCESS_DENIED; + DPRINT1("Internal ExitWindowsEx call not from winlogon\n"); + return STATUS_ACCESS_DENIED; } - DPRINT1("FIXME: Need to close all user processes!\n"); - return STATUS_SUCCESS; + DPRINT1("FIXME: Need to close all user processes!\n"); + return STATUS_SUCCESS; - CallerThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ThreadId); - if (NULL == CallerThread) + CallerThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ThreadId); + if (NULL == CallerThread) { - DPRINT1("OpenThread failed with error %d\n", GetLastError()); - return STATUS_UNSUCCESSFUL; + DPRINT1("OpenThread failed with error %d\n", GetLastError()); + return STATUS_UNSUCCESSFUL; } - if (! OpenThreadToken(CallerThread, TOKEN_QUERY, FALSE, &CallerToken)) + if (! OpenThreadToken(CallerThread, TOKEN_QUERY, FALSE, &CallerToken)) { - DPRINT1("OpenThreadToken failed with error %d\n", GetLastError()); - CloseHandle(CallerThread); - return STATUS_UNSUCCESSFUL; + DPRINT1("OpenThreadToken failed with error %d\n", GetLastError()); + CloseHandle(CallerThread); + return STATUS_UNSUCCESSFUL; } - CloseHandle(CallerThread); + CloseHandle(CallerThread); - Context.ProcessCount = 0; - Context.ProcessData = NULL; - if (! GetTokenInformation(CallerToken, TokenOrigin, &Context.TokenOrigin, - sizeof(TOKEN_ORIGIN), &ReturnLength)) + Context.ProcessCount = 0; + Context.ProcessData = NULL; + if (! GetTokenInformation(CallerToken, TokenOrigin, &Context.TokenOrigin, + sizeof(TOKEN_ORIGIN), &ReturnLength)) { - DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); - CloseHandle(CallerToken); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); + CloseHandle(CallerToken); + return STATUS_UNSUCCESSFUL; } - if (! GetTokenInformation(CallerToken, TokenUser, FixedUserInfo, - sizeof(FixedUserInfo), &ReturnLength)) + if (! GetTokenInformation(CallerToken, TokenUser, FixedUserInfo, + sizeof(FixedUserInfo), &ReturnLength)) { - if (sizeof(FixedUserInfo) < ReturnLength) + if (sizeof(FixedUserInfo) < ReturnLength) { - UserInfo = HeapAlloc(Win32CsrApiHeap, 0, ReturnLength); - if (NULL == UserInfo) + UserInfo = HeapAlloc(Win32CsrApiHeap, 0, ReturnLength); + if (NULL == UserInfo) { - DPRINT1("Unable to allocate %u bytes for user info\n", - (unsigned) ReturnLength); - CloseHandle(CallerToken); - return STATUS_NO_MEMORY; + DPRINT1("Unable to allocate %u bytes for user info\n", + (unsigned) ReturnLength); + CloseHandle(CallerToken); + return STATUS_NO_MEMORY; } - if (! GetTokenInformation(CallerToken, TokenUser, UserInfo, - ReturnLength, &ReturnLength)) + if (! GetTokenInformation(CallerToken, TokenUser, UserInfo, + ReturnLength, &ReturnLength)) { - DPRINT1("GetTokenInformation failed with error %d\n", - GetLastError()); - HeapFree(Win32CsrApiHeap, 0, UserInfo); - CloseHandle(CallerToken); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed with error %d\n", + GetLastError()); + HeapFree(Win32CsrApiHeap, 0, UserInfo); + CloseHandle(CallerToken); + return STATUS_UNSUCCESSFUL; } } - else + else { - DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); - CloseHandle(CallerToken); - return STATUS_UNSUCCESSFUL; + DPRINT1("GetTokenInformation failed with error %d\n", GetLastError()); + CloseHandle(CallerToken); + return STATUS_UNSUCCESSFUL; } } - else + else { - UserInfo = (TOKEN_USER *) FixedUserInfo; + UserInfo = (TOKEN_USER *) FixedUserInfo; } - CloseHandle(CallerToken); - LoadShutdownSettings(UserInfo->User.Sid, &ShutdownSettings); - if (UserInfo != (TOKEN_USER *) FixedUserInfo) + CloseHandle(CallerToken); + LoadShutdownSettings(UserInfo->User.Sid, &ShutdownSettings); + if (UserInfo != (TOKEN_USER *) FixedUserInfo) { - HeapFree(Win32CsrApiHeap, 0, UserInfo); + HeapFree(Win32CsrApiHeap, 0, UserInfo); } - Context.CsrssProcess = GetCurrentProcessId(); - ShellWnd = GetShellWindow(); - if (NULL == ShellWnd) + Context.CsrssProcess = GetCurrentProcessId(); + ShellWnd = GetShellWindow(); + if (NULL == ShellWnd) { - DPRINT("No shell present\n"); - Context.ShellProcess = 0; + DPRINT("No shell present\n"); + Context.ShellProcess = 0; } - else if (0 == GetWindowThreadProcessId(ShellWnd, &Context.ShellProcess)) + else if (0 == GetWindowThreadProcessId(ShellWnd, &Context.ShellProcess)) { - DPRINT1("Can't get process id of shell window\n"); - Context.ShellProcess = 0; + DPRINT1("Can't get process id of shell window\n"); + Context.ShellProcess = 0; } - Status = Win32CsrEnumProcesses(ExitReactosProcessEnum, &Context); - if (! NT_SUCCESS(Status)) + Status = Win32CsrEnumProcesses(ExitReactosProcessEnum, &Context); + if (! NT_SUCCESS(Status)) { - DPRINT1("Failed to enumerate registered processes, status 0x%x\n", - Status); - if (NULL != Context.ProcessData) + DPRINT1("Failed to enumerate registered processes, status 0x%x\n", + Status); + if (NULL != Context.ProcessData) { - HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); + HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); } - return Status; + return Status; } - qsort(Context.ProcessData, Context.ProcessCount, sizeof(PCSRSS_PROCESS_DATA), - ProcessDataCompare); + qsort(Context.ProcessData, Context.ProcessCount, sizeof(PCSRSS_PROCESS_DATA), + ProcessDataCompare); - /* Terminate processes, stop if we find one kicking and screaming it doesn't - want to die */ - Status = STATUS_SUCCESS; - for (ProcessIndex = 0; - ProcessIndex < Context.ProcessCount && NT_SUCCESS(Status); - ProcessIndex++) + /* Terminate processes, stop if we find one kicking and screaming it doesn't + want to die */ + Status = STATUS_SUCCESS; + for (ProcessIndex = 0; + ProcessIndex < Context.ProcessCount && NT_SUCCESS(Status); + ProcessIndex++) { - if (! NotifyAndTerminateProcess(Context.ProcessData[ProcessIndex], - &ShutdownSettings, Flags)) + if (! NotifyAndTerminateProcess(Context.ProcessData[ProcessIndex], + &ShutdownSettings, Flags)) { - Status = STATUS_REQUEST_ABORTED; + Status = STATUS_REQUEST_ABORTED; } } - /* Cleanup */ - if (NULL != Context.ProcessData) + /* Cleanup */ + if (NULL != Context.ProcessData) { - HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); + HeapFree(Win32CsrApiHeap, 0, Context.ProcessData); } - return Status; + return Status; } static NTSTATUS FASTCALL UserExitReactos(DWORD UserProcessId, UINT Flags) { - NTSTATUS Status; + NTSTATUS Status; - if (NULL == LogonNotifyWindow) + if (NULL == LogonNotifyWindow) { - DPRINT1("No LogonNotifyWindow registered\n"); - return STATUS_NOT_FOUND; + DPRINT1("No LogonNotifyWindow registered\n"); + return STATUS_NOT_FOUND; } - /* FIXME Inside 2000 says we should impersonate the caller here */ - Status = SendMessageW(LogonNotifyWindow, PM_WINLOGON_EXITWINDOWS, - (WPARAM) UserProcessId, - (LPARAM) Flags); - /* If the message isn't handled, the return value is 0, so 0 doesn't indicate - success. Success is indicated by a 1 return value, if anything besides 0 - or 1 it's a NTSTATUS value */ - if (1 == Status) + /* FIXME Inside 2000 says we should impersonate the caller here */ + Status = SendMessageW(LogonNotifyWindow, PM_WINLOGON_EXITWINDOWS, + (WPARAM) UserProcessId, + (LPARAM) Flags); + /* If the message isn't handled, the return value is 0, so 0 doesn't indicate + success. Success is indicated by a 1 return value, if anything besides 0 + or 1 it's a NTSTATUS value */ + if (1 == Status) { - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; } - else if (0 == Status) + else if (0 == Status) { - Status = STATUS_NOT_IMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; } - return Status; + return Status; } CSR_API(CsrExitReactos) { - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - - sizeof(PORT_MESSAGE); + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - + sizeof(PORT_MESSAGE); - if (0 == (Request->Data.ExitReactosRequest.Flags & EWX_INTERNAL_FLAG)) + if (0 == (Request->Data.ExitReactosRequest.Flags & EWX_INTERNAL_FLAG)) { - return UserExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, - Request->Data.ExitReactosRequest.Flags); + return UserExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, + Request->Data.ExitReactosRequest.Flags); } - else + else { - return InternalExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, - (DWORD_PTR) Request->Header.ClientId.UniqueThread, - Request->Data.ExitReactosRequest.Flags); + return InternalExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess, + (DWORD_PTR) Request->Header.ClientId.UniqueThread, + Request->Data.ExitReactosRequest.Flags); } } diff --git a/subsystems/win32/csrss/win32csr/guiconsole.c b/subsystems/win32/csrss/win32csr/guiconsole.c index 243246d5d47..d46d9cb4428 100644 --- a/subsystems/win32/csrss/win32csr/guiconsole.c +++ b/subsystems/win32/csrss/win32csr/guiconsole.c @@ -19,36 +19,30 @@ extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); typedef struct GUI_CONSOLE_DATA_TAG { - HFONT Font; - unsigned CharWidth; - unsigned CharHeight; - BOOL CursorBlinkOn; - BOOL ForceCursorOff; - CRITICAL_SECTION Lock; - RECT Selection; - POINT SelectionStart; - BOOL MouseDown; - HMODULE ConsoleLibrary; - HANDLE hGuiInitEvent; - WCHAR FontName[LF_FACESIZE]; - DWORD FontSize; - DWORD FontWeight; - DWORD HistoryNoDup; - DWORD FullScreen; - DWORD QuickEdit; - DWORD InsertMode; - DWORD NumberOfHistoryBuffers; - DWORD HistoryBufferSize; - DWORD WindowPosition; - DWORD UseRasterFonts; - COLORREF ScreenText; - COLORREF ScreenBackground; - COLORREF PopupBackground; - COLORREF PopupText; - COLORREF Colors[16]; - WCHAR szProcessName[MAX_PATH]; - BOOL WindowSizeLock; - POINT OldCursor; + HFONT Font; + unsigned CharWidth; + unsigned CharHeight; + BOOL CursorBlinkOn; + BOOL ForceCursorOff; + CRITICAL_SECTION Lock; + HMODULE ConsoleLibrary; + HANDLE hGuiInitEvent; + WCHAR FontName[LF_FACESIZE]; + DWORD FontSize; + DWORD FontWeight; + DWORD FullScreen; + DWORD QuickEdit; + DWORD InsertMode; + DWORD WindowPosition; + DWORD UseRasterFonts; + COLORREF ScreenText; + COLORREF ScreenBackground; + COLORREF PopupBackground; + COLORREF PopupText; + COLORREF Colors[16]; + WCHAR szProcessName[MAX_PATH]; + BOOL WindowSizeLock; + POINT OldCursor; } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA; #ifndef WM_APP @@ -116,7 +110,7 @@ static const COLORREF s_Colors[] = /* FUNCTIONS *****************************************************************/ -static VOID FASTCALL +static VOID GuiConsoleAppendMenuItems(HMENU hMenu, const GUICONSOLE_MENUITEM *Items) { @@ -167,11 +161,11 @@ GuiConsoleAppendMenuItems(HMENU hMenu, 0, NULL); } - i++; - }while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); + i++; + } while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } -static VOID FASTCALL +static VOID GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) { HMENU hMenu; @@ -185,209 +179,209 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) } } -static VOID FASTCALL +static VOID GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData) { - *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); - *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); + *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); + *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); } -static BOOL FASTCALL +static BOOL GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired) { - HANDLE hProcessToken = NULL; - HANDLE hProcess; + HANDLE hProcessToken = NULL; + HANDLE hProcess; - BYTE Buffer[256]; - DWORD Length = 0; - UNICODE_STRING SidName; - LONG res; - PTOKEN_USER TokUser; + BYTE Buffer[256]; + DWORD Length = 0; + UNICODE_STRING SidName; + LONG res; + PTOKEN_USER TokUser; - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); - if (!hProcess) + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); + if (!hProcess) { - DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); - return FALSE; + DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); + return FALSE; } - if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) + if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) { - DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); - CloseHandle(hProcess); - return FALSE; + DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); + CloseHandle(hProcess); + return FALSE; } - if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) + if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) { - DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); - CloseHandle(hProcess); - CloseHandle(hProcessToken); - return FALSE; + DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); + CloseHandle(hProcess); + CloseHandle(hProcessToken); + return FALSE; } - TokUser = ((PTOKEN_USER)Buffer)->User.Sid; - if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) + TokUser = ((PTOKEN_USER)Buffer)->User.Sid; + if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) { - DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); - return FALSE; + DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); + return FALSE; } - res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); - RtlFreeUnicodeString(&SidName); + res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); + RtlFreeUnicodeString(&SidName); - CloseHandle(hProcessToken); - if (hProcHandle) - *hProcHandle = hProcess; - else - CloseHandle(hProcess); + CloseHandle(hProcessToken); + if (hProcHandle) + *hProcHandle = hProcess; + else + CloseHandle(hProcess); - if (res != ERROR_SUCCESS) - return FALSE; - else - return TRUE; + if (res != ERROR_SUCCESS) + return FALSE; + else + return TRUE; } -static BOOL FASTCALL +static BOOL GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate) { - WCHAR szProcessName[MAX_PATH]; - WCHAR szBuffer[MAX_PATH]; - UINT fLength, wLength; - DWORD dwBitmask, dwLength; - WCHAR CurDrive[] = { 'A',':', 0 }; - HANDLE hProcess; - HKEY hKey; - WCHAR * ptr; + WCHAR szProcessName[MAX_PATH]; + WCHAR szBuffer[MAX_PATH]; + UINT fLength, wLength; + DWORD dwBitmask, dwLength; + WCHAR CurDrive[] = { 'A',':', 0 }; + HANDLE hProcess; + HKEY hKey; + WCHAR * ptr; - /* - * console properties are stored under - * HKCU\Console\* - * - * There are 3 ways to store console properties - * - * 1. use console title as subkey name - * i.e. cmd.exe - * - * 2. use application name as subkey name - * - * 3. use unexpanded path to console application. - * i.e. %SystemRoot%_system32_cmd.exe - */ + /* + * console properties are stored under + * HKCU\Console\* + * + * There are 3 ways to store console properties + * + * 1. use console title as subkey name + * i.e. cmd.exe + * + * 2. use application name as subkey name + * + * 3. use unexpanded path to console application. + * i.e. %SystemRoot%_system32_cmd.exe + */ - DPRINT("GuiConsoleOpenUserSettings entered\n"); + DPRINT("GuiConsoleOpenUserSettings entered\n"); - if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) + if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) { - DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); - return FALSE; + DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); + return FALSE; } - /* FIXME we do not getting the process name so no menu will be loading, why ?*/ - fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); - CloseHandle(hProcess); + /* FIXME we do not getting the process name so no menu will be loading, why ?*/ + fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); + CloseHandle(hProcess); - //DPRINT1("szProcessName3 : %S\n",szProcessName); + //DPRINT1("szProcessName3 : %S\n",szProcessName); - if (!fLength) + if (!fLength) { - DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); - return FALSE; + DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess); + return FALSE; } - /* - * try the process name as path - */ + /* + * try the process name as path + */ - ptr = wcsrchr(szProcessName, L'\\'); - wcscpy(GuiData->szProcessName, ptr); + ptr = wcsrchr(szProcessName, L'\\'); + wcscpy(GuiData->szProcessName, ptr); - swprintf(szBuffer, L"Console%s",ptr); - DPRINT("#1 Path : %S\n", szBuffer); + swprintf(szBuffer, L"Console%s",ptr); + DPRINT("#1 Path : %S\n", szBuffer); - if (bCreate) + if (bCreate) { - if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) + if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) { - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return TRUE; } - RegCloseKey(hKey); - return FALSE; - } - - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) - { - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return FALSE; } - /* - * try the "Shortcut to processname" as path - * FIXME: detect wheter the process was started as a shortcut - */ - - swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); - DPRINT("#2 Path : %S\n", szBuffer); - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); - RegCloseKey(hKey); - return TRUE; + RegCloseKey(hKey); + return TRUE; } - /* - * if the path contains \\Device\\HarddiskVolume1\... remove it - */ + /* + * try the "Shortcut to processname" as path + * FIXME: detect wheter the process was started as a shortcut + */ - if (szProcessName[0] == L'\\') + swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); + DPRINT("#2 Path : %S\n", szBuffer); + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - dwBitmask = GetLogicalDrives(); - while(dwBitmask) + swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); + RegCloseKey(hKey); + return TRUE; + } + + /* + * if the path contains \\Device\\HarddiskVolume1\... remove it + */ + + if (szProcessName[0] == L'\\') + { + dwBitmask = GetLogicalDrives(); + while(dwBitmask) { - if (dwBitmask & 0x1) + if (dwBitmask & 0x1) { - dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); - if (dwLength) + dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); + if (dwLength) { - if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) + if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) { - wcscpy(szProcessName, CurDrive); - RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); - break; + wcscpy(szProcessName, CurDrive); + RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); + break; } } } - dwBitmask = (dwBitmask >> 1); - CurDrive[0]++; + dwBitmask = (dwBitmask >> 1); + CurDrive[0]++; } } - /* - * last attempt: check whether the file is under %SystemRoot% - * and use path like Console\%SystemRoot%_dir_dir2_file.exe - */ + /* + * last attempt: check whether the file is under %SystemRoot% + * and use path like Console\%SystemRoot%_dir_dir2_file.exe + */ - wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); - if (wLength) + wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); + if (wLength) { - if (!wcsncmp(szProcessName, szBuffer, wLength)) + if (!wcsncmp(szProcessName, szBuffer, wLength)) { - /* replace slashes by underscores */ - while((ptr = wcschr(szProcessName, L'\\'))) - ptr[0] = L'_'; + /* replace slashes by underscores */ + while((ptr = wcschr(szProcessName, L'\\'))) + ptr[0] = L'_'; - swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]); - DPRINT("#3 Path : %S\n", szBuffer); - if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) + swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]); + DPRINT("#3 Path : %S\n", szBuffer); + if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) { - swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); - RegCloseKey(hKey); - return TRUE; + swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); + RegCloseKey(hKey); + return TRUE; } } } - RegCloseKey(hKey); - return FALSE; + RegCloseKey(hKey); + return FALSE; } static VOID @@ -397,238 +391,241 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) PCSRSS_PROCESS_DATA ProcessData; if (Console->ProcessList.Flink == &Console->ProcessList) - { + { DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n"); return; - } + } ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ | KEY_WRITE, TRUE)) - { + { return; - } - - if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) - { - RegDeleteKeyW(hKey, L"CursorSize"); - } - else - { - RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); } - if (GuiData->NumberOfHistoryBuffers == 5) + if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) { - RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); - } - else - { - RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD)); - } - - if (GuiData->HistoryBufferSize == 50) - { - RegDeleteKeyW(hKey, L"HistoryBufferSize"); - } - else - { - RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD)); - } - - if (GuiData->FullScreen == FALSE) - { - RegDeleteKeyW(hKey, L"FullScreen"); - } - else - { - RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); - } - - if ( GuiData->QuickEdit == FALSE) - { - RegDeleteKeyW(hKey, L"QuickEdit"); + RegDeleteKeyW(hKey, L"CursorSize"); } else { - RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); + RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); } - if (GuiData->InsertMode == TRUE) + if (Console->NumberOfHistoryBuffers == 5) { - RegDeleteKeyW(hKey, L"InsertMode"); + RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); } - else + else { - RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); + DWORD Temp = Console->NumberOfHistoryBuffers; + RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); } - if (GuiData->HistoryNoDup == FALSE) + if (Console->HistoryBufferSize == 50) { - RegDeleteKeyW(hKey, L"HistoryNoDup"); + RegDeleteKeyW(hKey, L"HistoryBufferSize"); } - else + else { - RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD)); + DWORD Temp = Console->HistoryBufferSize; + RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); } - if (GuiData->ScreenText == RGB(192, 192, 192)) + if (GuiData->FullScreen == FALSE) { - /* - * MS uses console attributes instead of real color - */ - RegDeleteKeyW(hKey, L"ScreenText"); + RegDeleteKeyW(hKey, L"FullScreen"); } - else + else { - RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); + RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); } - if (GuiData->ScreenBackground == RGB(0, 0, 0)) + if ( GuiData->QuickEdit == FALSE) { - RegDeleteKeyW(hKey, L"ScreenBackground"); + RegDeleteKeyW(hKey, L"QuickEdit"); } - else + else { - RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); + RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); } - RegCloseKey(hKey); + if (GuiData->InsertMode == TRUE) + { + RegDeleteKeyW(hKey, L"InsertMode"); + } + else + { + RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); + } + + if (Console->HistoryNoDup == FALSE) + { + RegDeleteKeyW(hKey, L"HistoryNoDup"); + } + else + { + DWORD Temp = Console->HistoryNoDup; + RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); + } + + if (GuiData->ScreenText == RGB(192, 192, 192)) + { + /* + * MS uses console attributes instead of real color + */ + RegDeleteKeyW(hKey, L"ScreenText"); + } + else + { + RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); + } + + if (GuiData->ScreenBackground == RGB(0, 0, 0)) + { + RegDeleteKeyW(hKey, L"ScreenBackground"); + } + else + { + RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); + } + + RegCloseKey(hKey); } -static void FASTCALL +static void GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { - DWORD dwNumSubKeys = 0; - DWORD dwIndex; - DWORD dwValueName; - DWORD dwValue; - DWORD dwType; - WCHAR szValueName[MAX_PATH]; - WCHAR szValue[LF_FACESIZE] = L"\0"; - DWORD Value; + DWORD dwNumSubKeys = 0; + DWORD dwIndex; + DWORD dwValueName; + DWORD dwValue; + DWORD dwType; + WCHAR szValueName[MAX_PATH]; + WCHAR szValue[LF_FACESIZE] = L"\0"; + DWORD Value; - if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { - DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); - return; + DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); + return; } - DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); + DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); - for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) + for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) { - dwValue = sizeof(Value); - dwValueName = MAX_PATH; + dwValue = sizeof(Value); + dwValueName = MAX_PATH; - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) { - if (dwType == REG_SZ) + if (dwType == REG_SZ) { - /* - * retry in case of string value - */ - dwValue = sizeof(szValue); - dwValueName = LF_FACESIZE; - if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) + /* + * retry in case of string value + */ + dwValue = sizeof(szValue); + dwValueName = LF_FACESIZE; + if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) + break; + } + else break; - } - else - break; } - if (!wcscmp(szValueName, L"CursorSize")) + if (!wcscmp(szValueName, L"CursorSize")) { - if (Value == 0x32) + if (Value == 0x32) { - Buffer->CursorInfo.dwSize = Value; + Buffer->CursorInfo.dwSize = Value; } - else if (Value == 0x64) + else if (Value == 0x64) { - Buffer->CursorInfo.dwSize = Value; + Buffer->CursorInfo.dwSize = Value; } } - else if (!wcscmp(szValueName, L"ScreenText")) + else if (!wcscmp(szValueName, L"ScreenText")) { - GuiData->ScreenText = Value; + GuiData->ScreenText = Value; } - else if (!wcscmp(szValueName, L"ScreenBackground")) + else if (!wcscmp(szValueName, L"ScreenBackground")) { - GuiData->ScreenBackground = Value; + GuiData->ScreenBackground = Value; } - else if (!wcscmp(szValueName, L"FaceName")) + else if (!wcscmp(szValueName, L"FaceName")) { - wcscpy(GuiData->FontName, szValue); + wcscpy(GuiData->FontName, szValue); } - else if (!wcscmp(szValueName, L"FontSize")) + else if (!wcscmp(szValueName, L"FontSize")) { - GuiData->FontSize = Value; + GuiData->FontSize = Value; } - else if (!wcscmp(szValueName, L"FontWeight")) + else if (!wcscmp(szValueName, L"FontWeight")) { - GuiData->FontWeight = Value; + GuiData->FontWeight = Value; } - else if (!wcscmp(szValueName, L"HistoryNoDup")) + else if (!wcscmp(szValueName, L"HistoryNoDup")) { - GuiData->HistoryNoDup = Value; + Console->HistoryNoDup = Value; } - else if (!wcscmp(szValueName, L"WindowSize")) + else if (!wcscmp(szValueName, L"WindowSize")) { - Console->Size.X = LOWORD(Value); - Console->Size.Y = HIWORD(Value); + Console->Size.X = LOWORD(Value); + Console->Size.Y = HIWORD(Value); } - else if (!wcscmp(szValueName, L"ScreenBufferSize")) + else if (!wcscmp(szValueName, L"ScreenBufferSize")) { if(Buffer) - { + { Buffer->MaxX = LOWORD(Value); Buffer->MaxY = HIWORD(Value); - } + } } - else if (!wcscmp(szValueName, L"FullScreen")) + else if (!wcscmp(szValueName, L"FullScreen")) { - GuiData->FullScreen = Value; + GuiData->FullScreen = Value; } - else if (!wcscmp(szValueName, L"QuickEdit")) + else if (!wcscmp(szValueName, L"QuickEdit")) { - GuiData->QuickEdit = Value; + GuiData->QuickEdit = Value; } - else if (!wcscmp(szValueName, L"InsertMode")) + else if (!wcscmp(szValueName, L"InsertMode")) { - GuiData->InsertMode = Value; + GuiData->InsertMode = Value; } - } + } } -static VOID FASTCALL +static VOID GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) { - /* - * init guidata with default properties - */ + /* + * init guidata with default properties + */ - wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); - GuiData->FontSize = 0x0008000C; // font is 8x12 - GuiData->FontWeight = FW_NORMAL; - GuiData->HistoryNoDup = FALSE; - GuiData->FullScreen = FALSE; - GuiData->QuickEdit = FALSE; - GuiData->InsertMode = TRUE; - GuiData->HistoryBufferSize = 50; - GuiData->NumberOfHistoryBuffers = 5; - GuiData->ScreenText = RGB(192, 192, 192); - GuiData->ScreenBackground = RGB(0, 0, 0); - GuiData->PopupText = RGB(128, 0, 128); - GuiData->PopupBackground = RGB(255, 255, 255); - GuiData->WindowPosition = UINT_MAX; - GuiData->UseRasterFonts = TRUE; - memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); + wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); + GuiData->FontSize = 0x0008000C; // font is 8x12 + GuiData->FontWeight = FW_NORMAL; + GuiData->FullScreen = FALSE; + GuiData->QuickEdit = FALSE; + GuiData->InsertMode = TRUE; + GuiData->ScreenText = RGB(192, 192, 192); + GuiData->ScreenBackground = RGB(0, 0, 0); + GuiData->PopupText = RGB(128, 0, 128); + GuiData->PopupBackground = RGB(255, 255, 255); + GuiData->WindowPosition = UINT_MAX; + GuiData->UseRasterFonts = TRUE; + memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); - Console->Size.X = 80; - Console->Size.Y = 25; + Console->HistoryBufferSize = 50; + Console->NumberOfHistoryBuffers = 5; + Console->HistoryNoDup = FALSE; + Console->Size.X = 80; + Console->Size.Y = 25; - if (Buffer) + if (Buffer) { - Buffer->MaxX = 80; - Buffer->MaxY = 300; - Buffer->CursorInfo.bVisible = TRUE; - Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; + Buffer->MaxX = 80; + Buffer->MaxY = 300; + Buffer->CursorInfo.bVisible = TRUE; + Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; } } @@ -636,225 +633,233 @@ VOID FASTCALL GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd) { - SCROLLINFO sInfo; - PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + SCROLLINFO sInfo; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; - DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - /* set scrollbar sizes */ - sInfo.cbSize = sizeof(SCROLLINFO); - sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - sInfo.nMin = 0; - if (Console->ActiveBuffer->MaxY > Console->Size.Y) - { - sInfo.nMax = Console->ActiveBuffer->MaxY - 1; - sInfo.nPage = Console->Size.Y; - sInfo.nPos = Console->ActiveBuffer->ShowY; - SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); - Width += GetSystemMetrics(SM_CXVSCROLL); - ShowScrollBar(hwnd, SB_VERT, TRUE); - } - else - { - ShowScrollBar(hwnd, SB_VERT, FALSE); - } + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + sInfo.nMin = 0; + if (Console->ActiveBuffer->MaxY > Console->Size.Y) + { + sInfo.nMax = Console->ActiveBuffer->MaxY - 1; + sInfo.nPage = Console->Size.Y; + sInfo.nPos = Console->ActiveBuffer->ShowY; + SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); + Width += GetSystemMetrics(SM_CXVSCROLL); + ShowScrollBar(hwnd, SB_VERT, TRUE); + } + else + { + ShowScrollBar(hwnd, SB_VERT, FALSE); + } - if (Console->ActiveBuffer->MaxX > Console->Size.X) - { - sInfo.nMax = Console->ActiveBuffer->MaxX - 1; - sInfo.nPage = Console->Size.X; - sInfo.nPos = Console->ActiveBuffer->ShowX; - SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); - Height += GetSystemMetrics(SM_CYHSCROLL); - ShowScrollBar(hwnd, SB_HORZ, TRUE); + if (Console->ActiveBuffer->MaxX > Console->Size.X) + { + sInfo.nMax = Console->ActiveBuffer->MaxX - 1; + sInfo.nPage = Console->Size.X; + sInfo.nPos = Console->ActiveBuffer->ShowX; + SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); + Height += GetSystemMetrics(SM_CYHSCROLL); + ShowScrollBar(hwnd, SB_HORZ, TRUE); - } - else - { - ShowScrollBar(hwnd, SB_HORZ, FALSE); - } + } + else + { + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } - SetWindowPos(hwnd, NULL, 0, 0, Width, Height, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + SetWindowPos(hwnd, NULL, 0, 0, Width, Height, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); } -static BOOL FASTCALL +static BOOL GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) { - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; - HDC Dc; - HFONT OldFont; - TEXTMETRICW Metrics; - SIZE CharSize; - PCSRSS_PROCESS_DATA ProcessData; - HKEY hKey; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; + PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; + HDC Dc; + HFONT OldFont; + TEXTMETRICW Metrics; + SIZE CharSize; + PCSRSS_PROCESS_DATA ProcessData; + HKEY hKey; - Console->hWindow = hWnd; + Console->hWindow = hWnd; - if (NULL == GuiData) + if (NULL == GuiData) { - DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); - return FALSE; + DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); + return FALSE; } - GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); - if (Console->ProcessList.Flink != &Console->ProcessList) + GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); + if (Console->ProcessList.Flink != &Console->ProcessList) { - ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); - if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) + ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry); + if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE)) { - GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); - RegCloseKey(hKey); + GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); + RegCloseKey(hKey); } } - InitializeCriticalSection(&GuiData->Lock); + InitializeCriticalSection(&GuiData->Lock); - GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), - 0, //HIWORD(GuiData->FontSize), - 0, - TA_BASELINE, - GuiData->FontWeight, - FALSE, - FALSE, - FALSE, - OEM_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, - GuiData->FontName); - if (NULL == GuiData->Font) + GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), + 0, //HIWORD(GuiData->FontSize), + 0, + TA_BASELINE, + GuiData->FontWeight, + FALSE, + FALSE, + FALSE, + OEM_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, + GuiData->FontName); + if (NULL == GuiData->Font) { - DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - Dc = GetDC(hWnd); - if (NULL == Dc) + Dc = GetDC(hWnd); + if (NULL == Dc) { - DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - OldFont = SelectObject(Dc, GuiData->Font); - if (NULL == OldFont) + OldFont = SelectObject(Dc, GuiData->Font); + if (NULL == OldFont) { - DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); - ReleaseDC(hWnd, Dc); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); + ReleaseDC(hWnd, Dc); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - if (! GetTextMetricsW(Dc, &Metrics)) + if (! GetTextMetricsW(Dc, &Metrics)) { - DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); - SelectObject(Dc, OldFont); - ReleaseDC(hWnd, Dc); - DeleteObject(GuiData->Font); - DeleteCriticalSection(&GuiData->Lock); - HeapFree(Win32CsrApiHeap, 0, GuiData); - return FALSE; + DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); + SelectObject(Dc, OldFont); + ReleaseDC(hWnd, Dc); + DeleteObject(GuiData->Font); + DeleteCriticalSection(&GuiData->Lock); + HeapFree(Win32CsrApiHeap, 0, GuiData); + return FALSE; } - GuiData->CharWidth = Metrics.tmMaxCharWidth; - GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; + GuiData->CharWidth = Metrics.tmMaxCharWidth; + GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; - /* Measure real char width more precisely if possible. */ - if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) - GuiData->CharWidth = CharSize.cx; + /* Measure real char width more precisely if possible. */ + if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) + GuiData->CharWidth = CharSize.cx; - SelectObject(Dc, OldFont); + SelectObject(Dc, OldFont); - ReleaseDC(hWnd, Dc); - GuiData->CursorBlinkOn = TRUE; - GuiData->ForceCursorOff = FALSE; + ReleaseDC(hWnd, Dc); + GuiData->CursorBlinkOn = TRUE; + GuiData->ForceCursorOff = FALSE; - GuiData->Selection.left = -1; - DPRINT("Console %p GuiData %p\n", Console, GuiData); - Console->PrivateData = GuiData; - SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); + DPRINT("Console %p GuiData %p\n", Console, GuiData); + Console->PrivateData = GuiData; + SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); - SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); - GuiConsoleCreateSysMenu(Console); + SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); + GuiConsoleCreateSysMenu(Console); - GuiData->WindowSizeLock = TRUE; - GuiConsoleInitScrollbar(Console, hWnd); - GuiData->WindowSizeLock = FALSE; + GuiData->WindowSizeLock = TRUE; + GuiConsoleInitScrollbar(Console, hWnd); + GuiData->WindowSizeLock = FALSE; - SetEvent(GuiData->hGuiInitEvent); + SetEvent(GuiData->hGuiInitEvent); - return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); + return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); } -static VOID FASTCALL -GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData) +static VOID +SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) { - RECT oldRect = GuiData->Selection; + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + Rect->left = (SmallRect->Left - Buffer->ShowX) * GuiData->CharWidth; + Rect->top = (SmallRect->Top - Buffer->ShowY) * GuiData->CharHeight; + Rect->right = (SmallRect->Right + 1 - Buffer->ShowX) * GuiData->CharWidth; + Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight; +} - if(rc != NULL) - { - RECT changeRect = *rc; +static VOID +GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) +{ + RECT oldRect, newRect; + HWND hWnd = Console->hWindow; - GuiData->Selection = *rc; + SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); - changeRect.left *= GuiData->CharWidth; - changeRect.top *= GuiData->CharHeight; - changeRect.right *= GuiData->CharWidth; - changeRect.bottom *= GuiData->CharHeight; - - if(rc->left != oldRect.left || - rc->top != oldRect.top || - rc->right != oldRect.right || - rc->bottom != oldRect.bottom) + if(coord != NULL) { - if(oldRect.left != -1) - { - HRGN rgn1, rgn2; + SMALL_RECT rc; + /* exchange left/top with right/bottom if required */ + rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); + rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); + rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y); - oldRect.left *= GuiData->CharWidth; - oldRect.top *= GuiData->CharHeight; - oldRect.right *= GuiData->CharWidth; - oldRect.bottom *= GuiData->CharHeight; + SmallRectToRect(Console, &newRect, &rc); - /* calculate the region that needs to be updated */ - if((rgn1 = CreateRectRgnIndirect(&oldRect))) + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - if((rgn2 = CreateRectRgnIndirect(&changeRect))) - { - if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) + if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0) { - InvalidateRgn(hWnd, rgn1, FALSE); - } + HRGN rgn1, rgn2; - DeleteObject(rgn2); - } - DeleteObject(rgn1); + /* calculate the region that needs to be updated */ + if((rgn1 = CreateRectRgnIndirect(&oldRect))) + { + if((rgn2 = CreateRectRgnIndirect(&newRect))) + { + if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) + { + InvalidateRgn(hWnd, rgn1, FALSE); + } + + DeleteObject(rgn2); + } + DeleteObject(rgn1); + } + } } - } - else - { - InvalidateRect(hWnd, &changeRect, FALSE); - } + else + { + InvalidateRect(hWnd, &newRect, FALSE); + } + Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; + Console->Selection.srSelection = rc; + ConioPause(Console, PAUSED_FROM_SELECTION); + } + else + { + /* clear the selection */ + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) + { + InvalidateRect(hWnd, &oldRect, FALSE); + } + Console->Selection.dwFlags = CONSOLE_NO_SELECTION; + ConioUnpause(Console, PAUSED_FROM_SELECTION); } - } - else if(oldRect.left != -1) - { - /* clear the selection */ - GuiData->Selection.left = -1; - oldRect.left *= GuiData->CharWidth; - oldRect.top *= GuiData->CharHeight; - oldRect.right *= GuiData->CharWidth; - oldRect.bottom *= GuiData->CharHeight; - InvalidateRect(hWnd, &oldRect, FALSE); - } } -static VOID FASTCALL +static VOID GuiConsolePaint(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, HDC hDC, @@ -872,7 +877,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, Buff = Console->ActiveBuffer; - EnterCriticalSection(&Buff->Header.Lock); + EnterCriticalSection(&Buff->Header.Console->Lock); TopLine = rc->top / GuiData->CharHeight + Buff->ShowY; BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY; @@ -934,12 +939,12 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, } if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn && - !GuiData->ForceCursorOff) + !GuiData->ForceCursorOff) { CursorX = Buff->CurrentX; CursorY = Buff->CurrentY; if (LeftChar <= CursorX && CursorX <= RightChar && - TopLine <= CursorY && CursorY <= BottomLine) + TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100; if (CursorHeight < 1) @@ -971,13 +976,13 @@ GuiConsolePaint(PCSRSS_CONSOLE Console, } } - LeaveCriticalSection(&Buff->Header.Lock); + LeaveCriticalSection(&Buff->Header.Console->Lock); SelectObject(hDC, OldFont); } -static VOID FASTCALL +static VOID GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) { HDC hDC; @@ -987,14 +992,14 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) hDC = BeginPaint(hWnd, &ps); if (hDC != NULL && - ps.rcPaint.left < ps.rcPaint.right && - ps.rcPaint.top < ps.rcPaint.bottom) + ps.rcPaint.left < ps.rcPaint.right && + ps.rcPaint.top < ps.rcPaint.bottom) { GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); if (Console != NULL && GuiData != NULL && - Console->ActiveBuffer != NULL) + Console->ActiveBuffer != NULL) { if (Console->ActiveBuffer->Buffer != NULL) { @@ -1005,14 +1010,10 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) hDC, &ps.rcPaint); - if (GuiData->Selection.left != -1) + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - RECT rc = GuiData->Selection; - - rc.left *= GuiData->CharWidth; - rc.top *= GuiData->CharHeight; - rc.right *= GuiData->CharWidth; - rc.bottom *= GuiData->CharHeight; + RECT rc; + SmallRectToRect(Console, &rc, &Console->Selection.srSelection); /* invert the selection */ if (IntersectRect(&rc, @@ -1036,130 +1037,89 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) EndPaint(hWnd, &ps); } -static VOID FASTCALL +static VOID GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - MSG Message; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + MSG Message; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - Message.hwnd = hWnd; - Message.message = msg; - Message.wParam = wParam; - Message.lParam = lParam; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + Message.hwnd = hWnd; + Message.message = msg; + Message.wParam = wParam; + Message.lParam = lParam; - if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) - { - /* clear the selection */ - GuiConsoleUpdateSelection(hWnd, NULL, GuiData); - } - - ConioProcessKey(&Message, Console, FALSE); -} - -static VOID FASTCALL -GuiIntDrawRegion(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region) -{ - RECT RegionRect; - - RegionRect.left = (Region->left - Buff->ShowX) * GuiData->CharWidth; - RegionRect.top = (Region->top - Buff->ShowY) * GuiData->CharHeight; - RegionRect.right = (Region->right + 1 - Buff->ShowX) * GuiData->CharWidth; - RegionRect.bottom = (Region->bottom + 1 - Buff->ShowY) * GuiData->CharHeight; - - InvalidateRect(Wnd, &RegionRect, FALSE); -} - -static VOID WINAPI -GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) -{ - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; - - if (NULL != Console->hWindow && NULL != GuiData) + if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) { - GuiIntDrawRegion(Console->ActiveBuffer, GuiData, Console->hWindow, Region); + /* clear the selection */ + GuiConsoleUpdateSelection(Console, NULL); } -} -static VOID FASTCALL -GuiInvalidateCell(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y) -{ - RECT CellRect; - - CellRect.left = x; - CellRect.top = y; - CellRect.right = x; - CellRect.bottom = y; - - GuiIntDrawRegion(Buff, GuiData, Wnd, &CellRect); + ConioProcessKey(&Message, Console, FALSE); } static VOID WINAPI -GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY, +GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) +{ + RECT RegionRect; + SmallRectToRect(Console, &RegionRect, Region); + InvalidateRect(Console->hWindow, &RegionRect, FALSE); +} + +static VOID +GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y) +{ + SMALL_RECT CellRect = { x, y, x, y }; + GuiDrawRegion(Console, &CellRect); +} + +static VOID WINAPI +GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { - PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - LONG CursorEndX, CursorEndY; - RECT ScrollRect; + PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + LONG CursorEndX, CursorEndY; + RECT ScrollRect; - if (NULL == Console->hWindow || NULL == GuiData) + if (NULL == Console->hWindow || NULL == GuiData) { - return; + return; } - if (0 != ScrolledLines) + if (0 != ScrolledLines) { - ScrollRect.left = 0; - ScrollRect.top = 0; - ScrollRect.right = Console->Size.X * GuiData->CharWidth; - ScrollRect.bottom = Region->top * GuiData->CharHeight; + ScrollRect.left = 0; + ScrollRect.top = 0; + ScrollRect.right = Console->Size.X * GuiData->CharWidth; + ScrollRect.bottom = Region->Top * GuiData->CharHeight; - if (GuiData->Selection.left != -1) - { - /* scroll the selection */ - if (GuiData->Selection.top > ScrolledLines) - { - GuiData->Selection.top -= ScrolledLines; - GuiData->Selection.bottom -= ScrolledLines; - } - else if (GuiData->Selection.bottom < ScrolledLines) - { - GuiData->Selection.left = -1; - } - else - { - GuiData->Selection.top = 0; - GuiData->Selection.bottom -= ScrolledLines; - } - } - - ScrollWindowEx(Console->hWindow, - 0, - -(ScrolledLines * GuiData->CharHeight), - &ScrollRect, - NULL, - NULL, - NULL, - SW_INVALIDATE); + ScrollWindowEx(Console->hWindow, + 0, + -(ScrolledLines * GuiData->CharHeight), + &ScrollRect, + NULL, + NULL, + NULL, + SW_INVALIDATE); } - GuiIntDrawRegion(Buff, GuiData, Console->hWindow, Region); + GuiDrawRegion(Console, Region); - if (CursorStartX < Region->left || Region->right < CursorStartX - || CursorStartY < Region->top || Region->bottom < CursorStartY) + if (CursorStartX < Region->Left || Region->Right < CursorStartX + || CursorStartY < Region->Top || Region->Bottom < CursorStartY) { - GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorStartX, CursorStartY); + GuiInvalidateCell(Console, CursorStartX, CursorStartY); } - CursorEndX = Buff->CurrentX; - CursorEndY = Buff->CurrentY; - if ((CursorEndX < Region->left || Region->right < CursorEndX - || CursorEndY < Region->top || Region->bottom < CursorEndY) - && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) + CursorEndX = Buff->CurrentX; + CursorEndY = Buff->CurrentY; + if ((CursorEndX < Region->Left || Region->Right < CursorEndX + || CursorEndY < Region->Top || Region->Bottom < CursorEndY) + && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) { - GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorEndX, CursorEndY); + GuiInvalidateCell(Console, CursorEndX, CursorEndY); } // Set up the update timer (very short interval) - this is a "hack" for getting the OS to @@ -1171,42 +1131,26 @@ GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG Cur static BOOL WINAPI GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) { - RECT UpdateRect; - - if (Console->ActiveBuffer == Buff) + if (Console->ActiveBuffer == Buff) { - UpdateRect.left = Buff->CurrentX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = UpdateRect.left; - UpdateRect.bottom = UpdateRect.top; - ConioDrawRegion(Console, &UpdateRect); + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } - return TRUE; + return TRUE; } static BOOL WINAPI GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) { - RECT UpdateRect; - - if (Console->ActiveBuffer == Buff) + if (Console->ActiveBuffer == Buff) { - /* Redraw char at old position (removes cursor) */ - UpdateRect.left = OldCursorX; - UpdateRect.top = OldCursorY; - UpdateRect.right = OldCursorX; - UpdateRect.bottom = OldCursorY; - ConioDrawRegion(Console, &UpdateRect); - /* Redraw char at new position (shows cursor) */ - UpdateRect.left = Buff->CurrentX; - UpdateRect.top = Buff->CurrentY; - UpdateRect.right = UpdateRect.left; - UpdateRect.bottom = UpdateRect.top; - ConioDrawRegion(Console, &UpdateRect); + /* Redraw char at old position (removes cursor) */ + GuiInvalidateCell(Console, OldCursorX, OldCursorY); + /* Redraw char at new position (shows cursor) */ + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); } - return TRUE; + return TRUE; } static BOOL WINAPI @@ -1223,281 +1167,232 @@ GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) return TRUE; } -static VOID FASTCALL +static VOID GuiConsoleHandleTimer(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - PCSRSS_SCREEN_BUFFER Buff; - RECT CursorRect; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + PCSRSS_SCREEN_BUFFER Buff; - SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); + SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - Buff = Console->ActiveBuffer; - CursorRect.left = Buff->CurrentX; - CursorRect.top = Buff->CurrentY; - CursorRect.right = CursorRect.left; - CursorRect.bottom = CursorRect.top; - GuiDrawRegion(Console, &CursorRect); - GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; + Buff = Console->ActiveBuffer; + GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); + GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; - if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) - { - SCROLLINFO xScroll; - int OldScrollX = -1, OldScrollY = -1; - int NewScrollX = -1, NewScrollY = -1; + if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) + { + SCROLLINFO xScroll; + int OldScrollX = -1, OldScrollY = -1; + int NewScrollX = -1, NewScrollY = -1; - xScroll.cbSize = sizeof(SCROLLINFO); - xScroll.fMask = SIF_POS; - // Capture the original position of the scroll bars and save them. - if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos; - if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos; + xScroll.cbSize = sizeof(SCROLLINFO); + xScroll.fMask = SIF_POS; + // Capture the original position of the scroll bars and save them. + if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos; + if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos; - // If we successfully got the info for the horizontal scrollbar - if(OldScrollX >= 0) - { - if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X))) - { - // Handle the horizontal scroll bar - if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; - else NewScrollX = 0; - } - else - { - NewScrollX = OldScrollX; - } - } - // If we successfully got the info for the vertical scrollbar - if(OldScrollY >= 0) - { - if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y))) + // If we successfully got the info for the horizontal scrollbar + if(OldScrollX >= 0) { - // Handle the vertical scroll bar - if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; - else NewScrollY = 0; + if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X))) + { + // Handle the horizontal scroll bar + if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; + else NewScrollX = 0; + } + else + { + NewScrollX = OldScrollX; + } } - else + // If we successfully got the info for the vertical scrollbar + if(OldScrollY >= 0) { - NewScrollY = OldScrollY; + if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y))) + { + // Handle the vertical scroll bar + if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; + else NewScrollY = 0; + } + else + { + NewScrollY = OldScrollY; + } } - } - // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area - // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar - // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling) - // and their associated scrollbar is left alone. - if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY)) - { - Buff->ShowX = NewScrollX; - Buff->ShowY = NewScrollY; - ScrollWindowEx(hWnd, - (OldScrollX - NewScrollX) * GuiData->CharWidth, - (OldScrollY - NewScrollY) * GuiData->CharHeight, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); - if(NewScrollX >= 0) + // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area + // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar + // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling) + // and their associated scrollbar is left alone. + if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY)) { - xScroll.nPos = NewScrollX; - SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE); + Buff->ShowX = NewScrollX; + Buff->ShowY = NewScrollY; + ScrollWindowEx(hWnd, + (OldScrollX - NewScrollX) * GuiData->CharWidth, + (OldScrollY - NewScrollY) * GuiData->CharHeight, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + if(NewScrollX >= 0) + { + xScroll.nPos = NewScrollX; + SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE); + } + if(NewScrollY >= 0) + { + xScroll.nPos = NewScrollY; + SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); + } + UpdateWindow(hWnd); + GuiData->OldCursor.x = Buff->CurrentX; + GuiData->OldCursor.y = Buff->CurrentY; } - if(NewScrollY >= 0) - { - xScroll.nPos = NewScrollY; - SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); - } - UpdateWindow(hWnd); - GuiData->OldCursor.x = Buff->CurrentX; - GuiData->OldCursor.y = Buff->CurrentY; - } - } + } } -static VOID FASTCALL +static VOID GuiConsoleHandleClose(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - PLIST_ENTRY current_entry; - PCSRSS_PROCESS_DATA current; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + PLIST_ENTRY current_entry; + PCSRSS_PROCESS_DATA current; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - EnterCriticalSection(&Console->Header.Lock); + EnterCriticalSection(&Console->Lock); - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) { - current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); - current_entry = current_entry->Flink; + current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry); + current_entry = current_entry->Flink; - /* FIXME: Windows will wait up to 5 seconds for the thread to exit. - * We shouldn't wait here, though, since the console lock is entered. - * A copy of the thread list probably needs to be made. */ - ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); + /* FIXME: Windows will wait up to 5 seconds for the thread to exit. + * We shouldn't wait here, though, since the console lock is entered. + * A copy of the thread list probably needs to be made. */ + ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); } - LeaveCriticalSection(&Console->Header.Lock); + LeaveCriticalSection(&Console->Lock); } -static VOID FASTCALL +static VOID GuiConsoleHandleNcDestroy(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - KillTimer(hWnd, 1); - Console->PrivateData = NULL; - DeleteCriticalSection(&GuiData->Lock); - GetSystemMenu(hWnd, TRUE); - if (GuiData->ConsoleLibrary) - FreeLibrary(GuiData->ConsoleLibrary); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + KillTimer(hWnd, 1); + Console->PrivateData = NULL; + DeleteCriticalSection(&GuiData->Lock); + GetSystemMenu(hWnd, TRUE); + if (GuiData->ConsoleLibrary) + FreeLibrary(GuiData->ConsoleLibrary); - HeapFree(Win32CsrApiHeap, 0, GuiData); + HeapFree(Win32CsrApiHeap, 0, GuiData); } -static VOID FASTCALL +static COORD +PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam) +{ + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = Console->PrivateData; + COORD Coord; + Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth); + Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight); + + /* Clip coordinate to ensure it's inside buffer */ + if (Coord.X < 0) Coord.X = 0; + else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1; + if (Coord.Y < 0) Coord.Y = 0; + else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1; + return Coord; +} + +static VOID GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - POINTS pt; - RECT rc; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; - pt = MAKEPOINTS(lParam); + Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam); - rc.left = pt.x / GuiData->CharWidth; - rc.top = pt.y / GuiData->CharHeight; - rc.right = rc.left + 1; - rc.bottom = rc.top + 1; + SetCapture(hWnd); - GuiData->SelectionStart.x = rc.left; - GuiData->SelectionStart.y = rc.top; + Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; - SetCapture(hWnd); - - GuiData->MouseDown = TRUE; - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); } -static VOID FASTCALL +static VOID GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - RECT rc; - POINTS pt; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD c; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; - if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - pt = MAKEPOINTS(lParam); + c = PointToCoord(Console, lParam); - rc.left = GuiData->SelectionStart.x; - rc.top = GuiData->SelectionStart.y; - rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0); - rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0); + Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; - /* exchange left/top with right/bottom if required */ - if(rc.left >= rc.right) - { - LONG tmp; - tmp = rc.left; - rc.left = max(rc.right - 1, 0); - rc.right = tmp + 1; - } - if(rc.top >= rc.bottom) - { - LONG tmp; - tmp = rc.top; - rc.top = max(rc.bottom - 1, 0); - rc.bottom = tmp + 1; - } + GuiConsoleUpdateSelection(Console, &c); - GuiData->MouseDown = FALSE; - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); - - ReleaseCapture(); + ReleaseCapture(); } -static VOID FASTCALL +static VOID GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - RECT rc; - POINTS pt; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD c; - if (!(wParam & MK_LBUTTON)) return; + if (!(wParam & MK_LBUTTON)) return; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; + if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; - pt = MAKEPOINTS(lParam); + c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ - rc.left = GuiData->SelectionStart.x; - rc.top = GuiData->SelectionStart.y; - rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0); - if (Console->Size.X < rc.right) - { - rc.right = Console->Size.X; - } - rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0); - if (Console->Size.Y < rc.bottom) - { - rc.bottom = Console->Size.Y; - } - - /* exchange left/top with right/bottom if required */ - if(rc.left >= rc.right) - { - LONG tmp; - tmp = rc.left; - rc.left = max(rc.right - 1, 0); - rc.right = tmp + 1; - } - if(rc.top >= rc.bottom) - { - LONG tmp; - tmp = rc.top; - rc.top = max(rc.bottom - 1, 0); - rc.bottom = tmp + 1; - } - - GuiConsoleUpdateSelection(hWnd, &rc, GuiData); + GuiConsoleUpdateSelection(Console, &c); } -static VOID FASTCALL +static VOID GuiConsoleRightMouseDown(HWND hWnd) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) return; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) return; - if (GuiData->Selection.left == -1) - { - /* FIXME - paste text from clipboard */ - } - else - { - /* FIXME - copy selection to clipboard */ + if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) + { + /* FIXME - paste text from clipboard */ + } + else + { + /* FIXME - copy selection to clipboard */ - GuiConsoleUpdateSelection(hWnd, NULL, GuiData); - } + GuiConsoleUpdateSelection(Console, NULL); + } } @@ -1505,206 +1400,207 @@ GuiConsoleRightMouseDown(HWND hWnd) static VOID GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData) { - PCSRSS_CONSOLE Console; - APPLET_PROC CPLFunc; - TCHAR szBuffer[MAX_PATH]; - ConsoleInfo SharedInfo; + PCSRSS_CONSOLE Console; + APPLET_PROC CPLFunc; + TCHAR szBuffer[MAX_PATH]; + ConsoleInfo SharedInfo; - DPRINT("GuiConsoleShowConsoleProperties entered\n"); + DPRINT("GuiConsoleShowConsoleProperties entered\n"); - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if (GuiData == NULL) + if (GuiData == NULL) { - DPRINT("GuiConsoleGetDataPointers failed\n"); - return; + DPRINT("GuiConsoleGetDataPointers failed\n"); + return; } - if (GuiData->ConsoleLibrary == NULL) + if (GuiData->ConsoleLibrary == NULL) { - GetWindowsDirectory(szBuffer,MAX_PATH); - _tcscat(szBuffer, _T("\\system32\\console.dll")); - GuiData->ConsoleLibrary = LoadLibrary(szBuffer); + GetWindowsDirectory(szBuffer,MAX_PATH); + _tcscat(szBuffer, _T("\\system32\\console.dll")); + GuiData->ConsoleLibrary = LoadLibrary(szBuffer); - if (GuiData->ConsoleLibrary == NULL) + if (GuiData->ConsoleLibrary == NULL) { - DPRINT1("failed to load console.dll"); - return; + DPRINT1("failed to load console.dll"); + return; } } - CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); - if (!CPLFunc) + CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); + if (!CPLFunc) { - DPRINT("Error: Console.dll misses CPlApplet export\n"); - return; + DPRINT("Error: Console.dll misses CPlApplet export\n"); + return; } - /* setup struct */ - SharedInfo.InsertMode = GuiData->InsertMode; - SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize; - SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers; - SharedInfo.ScreenText = GuiData->ScreenText; - SharedInfo.ScreenBackground = GuiData->ScreenBackground; - SharedInfo.PopupText = GuiData->PopupText; - SharedInfo.PopupBackground = GuiData->PopupBackground; - SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); - SharedInfo.WindowPosition = GuiData->WindowPosition; - SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY); - SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; - SharedInfo.FontSize = (DWORD)GuiData->FontSize; - SharedInfo.FontWeight = GuiData->FontWeight; - SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; - SharedInfo.HistoryNoDup = GuiData->HistoryNoDup; - SharedInfo.FullScreen = GuiData->FullScreen; - SharedInfo.QuickEdit = GuiData->QuickEdit; - memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); + /* setup struct */ + SharedInfo.InsertMode = GuiData->InsertMode; + SharedInfo.HistoryBufferSize = Console->HistoryBufferSize; + SharedInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; + SharedInfo.ScreenText = GuiData->ScreenText; + SharedInfo.ScreenBackground = GuiData->ScreenBackground; + SharedInfo.PopupText = GuiData->PopupText; + SharedInfo.PopupBackground = GuiData->PopupBackground; + SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); + SharedInfo.WindowPosition = GuiData->WindowPosition; + SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY); + SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; + SharedInfo.FontSize = (DWORD)GuiData->FontSize; + SharedInfo.FontWeight = GuiData->FontWeight; + SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; + SharedInfo.HistoryNoDup = Console->HistoryNoDup; + SharedInfo.FullScreen = GuiData->FullScreen; + SharedInfo.QuickEdit = GuiData->QuickEdit; + memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); - if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) + if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) { - DPRINT("Error: failed to initialize console.dll\n"); - return; + DPRINT("Error: failed to initialize console.dll\n"); + return; } - if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) + if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) { - DPRINT("Error: console.dll returned unexpected CPL count\n"); - return; + DPRINT("Error: console.dll returned unexpected CPL count\n"); + return; } - CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); + CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); } -static LRESULT FASTCALL +static LRESULT GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData) { LRESULT Ret = TRUE; switch(wParam) { - case ID_SYSTEM_EDIT_MARK: - case ID_SYSTEM_EDIT_COPY: - case ID_SYSTEM_EDIT_PASTE: - case ID_SYSTEM_EDIT_SELECTALL: - case ID_SYSTEM_EDIT_SCROLL: - case ID_SYSTEM_EDIT_FIND: - break; + case ID_SYSTEM_EDIT_MARK: + case ID_SYSTEM_EDIT_COPY: + case ID_SYSTEM_EDIT_PASTE: + case ID_SYSTEM_EDIT_SELECTALL: + case ID_SYSTEM_EDIT_SCROLL: + case ID_SYSTEM_EDIT_FIND: + break; - case ID_SYSTEM_DEFAULTS: - GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); - break; + case ID_SYSTEM_DEFAULTS: + GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); + break; - case ID_SYSTEM_PROPERTIES: - GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); - break; + case ID_SYSTEM_PROPERTIES: + GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); + break; - default: - Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); - break; + default: + Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); + break; } return Ret; } -static VOID FASTCALL +static VOID GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if((Console == NULL)|| (GuiData == NULL)) return; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if((Console == NULL)|| (GuiData == NULL)) return; - DWORD windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - DWORD windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + DWORD windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + DWORD windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - minMaxInfo->ptMinTrackSize.x = windx; - minMaxInfo->ptMinTrackSize.y = windy; + minMaxInfo->ptMinTrackSize.x = windx; + minMaxInfo->ptMinTrackSize.y = windy; - windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); - windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); + windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); + windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); - if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar - if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar + if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar + if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar - minMaxInfo->ptMaxTrackSize.x = windx; - minMaxInfo->ptMaxTrackSize.y = windy; + minMaxInfo->ptMaxTrackSize.x = windx; + minMaxInfo->ptMaxTrackSize.y = windy; } -static VOID FASTCALL +static VOID GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) { - PCSRSS_CONSOLE Console; - PGUI_CONSOLE_DATA GuiData; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - if((Console == NULL) || (GuiData == NULL)) return; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + if((Console == NULL) || (GuiData == NULL)) return; - if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) - { - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) + { + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - GuiData->WindowSizeLock = TRUE; + GuiData->WindowSizeLock = TRUE; - DWORD windx = LOWORD(lParam); - DWORD windy = HIWORD(lParam); + DWORD windx = LOWORD(lParam); + DWORD windy = HIWORD(lParam); - // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) - if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar - if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar + // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) + if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar + if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar - DWORD charx = windx / GuiData->CharWidth; - DWORD chary = windy / GuiData->CharHeight; + DWORD charx = windx / GuiData->CharWidth; + DWORD chary = windy / GuiData->CharHeight; - // Character alignment (round size up or down) - if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; - if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; + // Character alignment (round size up or down) + if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; + if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; - // Compensate for added scroll bars in new window - if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar - if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar + // Compensate for added scroll bars in new window + if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar + if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar - charx = windx / GuiData->CharWidth; - chary = windy / GuiData->CharHeight; + charx = windx / GuiData->CharWidth; + chary = windy / GuiData->CharHeight; - // Character alignment (round size up or down) - if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; - if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; + // Character alignment (round size up or down) + if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; + if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; - // Resize window - if((charx != Console->Size.X) || (chary != Console->Size.Y)) - { - Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX; - Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY; - } + // Resize window + if((charx != Console->Size.X) || (chary != Console->Size.Y)) + { + Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX; + Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY; + } - GuiConsoleInitScrollbar(Console, hWnd); + GuiConsoleInitScrollbar(Console, hWnd); - // Adjust the start of the visible area if we are attempting to show nonexistent areas - if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X; - if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y; - InvalidateRect(hWnd, NULL, TRUE); + // Adjust the start of the visible area if we are attempting to show nonexistent areas + if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X; + if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y; + InvalidateRect(hWnd, NULL, TRUE); - GuiData->WindowSizeLock = FALSE; - } + GuiData->WindowSizeLock = FALSE; + } } + VOID FASTCALL GuiConsoleHandleScrollbarMenu() { - HMENU hMenu; + HMENU hMenu; - hMenu = CreatePopupMenu(); - if (hMenu == NULL) + hMenu = CreatePopupMenu(); + if (hMenu == NULL) { - DPRINT("CreatePopupMenu failed\n"); - return; + DPRINT("CreatePopupMenu failed\n"); + return; } - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); - //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); - //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); + //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); + //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); } @@ -1801,256 +1697,261 @@ GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD return STATUS_SUCCESS; } -static VOID FASTCALL +static VOID GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) { - DWORD windx, windy; - PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; - COORD BufSize; - BOOL SizeChanged = FALSE; + DWORD windx, windy; + PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; + COORD BufSize; + BOOL SizeChanged = FALSE; - EnterCriticalSection(&ActiveBuffer->Header.Lock); + EnterCriticalSection(&Console->Lock); - /* apply text / background color */ - GuiData->ScreenText = pConInfo->ScreenText; - GuiData->ScreenBackground = pConInfo->ScreenBackground; + /* apply text / background color */ + GuiData->ScreenText = pConInfo->ScreenText; + GuiData->ScreenBackground = pConInfo->ScreenBackground; - /* apply cursor size */ - ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); + /* apply cursor size */ + ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); - windx = LOWORD(pConInfo->WindowSize); - windy = HIWORD(pConInfo->WindowSize); + windx = LOWORD(pConInfo->WindowSize); + windy = HIWORD(pConInfo->WindowSize); - if (windx != Console->Size.X || windy != Console->Size.Y) - { - /* resize window */ - Console->Size.X = windx; - Console->Size.Y = windy; - SizeChanged = TRUE; - } + if (windx != Console->Size.X || windy != Console->Size.Y) + { + /* resize window */ + Console->Size.X = windx; + Console->Size.Y = windy; + SizeChanged = TRUE; + } - BufSize.X = LOWORD(pConInfo->ScreenBuffer); - BufSize.Y = HIWORD(pConInfo->ScreenBuffer); - if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) - { - if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) - SizeChanged = TRUE; - } + BufSize.X = LOWORD(pConInfo->ScreenBuffer); + BufSize.Y = HIWORD(pConInfo->ScreenBuffer); + if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) + { + if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) + SizeChanged = TRUE; + } - if (SizeChanged) - { - GuiData->WindowSizeLock = TRUE; - GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); - GuiData->WindowSizeLock = FALSE; - } + if (SizeChanged) + { + GuiData->WindowSizeLock = TRUE; + GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); + GuiData->WindowSizeLock = FALSE; + } - LeaveCriticalSection(&ActiveBuffer->Header.Lock); - InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); + LeaveCriticalSection(&Console->Lock); + InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); } static LRESULT GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam) { - PCSRSS_CONSOLE Console; - PCSRSS_SCREEN_BUFFER Buff; - PGUI_CONSOLE_DATA GuiData; - SCROLLINFO sInfo; - int fnBar; - int old_pos, Maximum; - PUSHORT pShowXY; + PCSRSS_CONSOLE Console; + PCSRSS_SCREEN_BUFFER Buff; + PGUI_CONSOLE_DATA GuiData; + SCROLLINFO sInfo; + int fnBar; + int old_pos, Maximum; + PUSHORT pShowXY; - GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); - if (Console == NULL || GuiData == NULL) - return FALSE; - Buff = Console->ActiveBuffer; + GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); + if (Console == NULL || GuiData == NULL) + return FALSE; + Buff = Console->ActiveBuffer; - if (uMsg == WM_HSCROLL) - { - fnBar = SB_HORZ; - Maximum = Buff->MaxX - Console->Size.X; - pShowXY = &Buff->ShowX; - } - else - { - fnBar = SB_VERT; - Maximum = Buff->MaxY - Console->Size.Y; - pShowXY = &Buff->ShowY; - } + if (uMsg == WM_HSCROLL) + { + fnBar = SB_HORZ; + Maximum = Buff->MaxX - Console->Size.X; + pShowXY = &Buff->ShowX; + } + else + { + fnBar = SB_VERT; + Maximum = Buff->MaxY - Console->Size.Y; + pShowXY = &Buff->ShowY; + } - /* set scrollbar sizes */ - sInfo.cbSize = sizeof(SCROLLINFO); - sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; + /* set scrollbar sizes */ + sInfo.cbSize = sizeof(SCROLLINFO); + sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; - if (!GetScrollInfo(hwnd, fnBar, &sInfo)) - { - return FALSE; - } + if (!GetScrollInfo(hwnd, fnBar, &sInfo)) + { + return FALSE; + } - old_pos = sInfo.nPos; + old_pos = sInfo.nPos; - switch(LOWORD(wParam)) - { - case SB_LINELEFT: - sInfo.nPos -= 1; - break; + switch(LOWORD(wParam)) + { + case SB_LINELEFT: + sInfo.nPos -= 1; + break; - case SB_LINERIGHT: - sInfo.nPos += 1; - break; + case SB_LINERIGHT: + sInfo.nPos += 1; + break; - case SB_PAGELEFT: - sInfo.nPos -= sInfo.nPage; - break; + case SB_PAGELEFT: + sInfo.nPos -= sInfo.nPage; + break; - case SB_PAGERIGHT: - sInfo.nPos += sInfo.nPage; - break; + case SB_PAGERIGHT: + sInfo.nPos += sInfo.nPage; + break; - case SB_THUMBTRACK: - sInfo.nPos = sInfo.nTrackPos; - break; + case SB_THUMBTRACK: + sInfo.nPos = sInfo.nTrackPos; + ConioPause(Console, PAUSED_FROM_SCROLLBAR); + break; - case SB_TOP: - sInfo.nPos = sInfo.nMin; - break; + case SB_THUMBPOSITION: + ConioUnpause(Console, PAUSED_FROM_SCROLLBAR); + break; - case SB_BOTTOM: - sInfo.nPos = sInfo.nMax; - break; + case SB_TOP: + sInfo.nPos = sInfo.nMin; + break; - default: - break; - } + case SB_BOTTOM: + sInfo.nPos = sInfo.nMax; + break; - sInfo.nPos = max(sInfo.nPos, 0); - sInfo.nPos = min(sInfo.nPos, Maximum); + default: + break; + } - if (old_pos != sInfo.nPos) - { - USHORT OldX = Buff->ShowX; - USHORT OldY = Buff->ShowY; - *pShowXY = sInfo.nPos; + sInfo.nPos = max(sInfo.nPos, 0); + sInfo.nPos = min(sInfo.nPos, Maximum); - ScrollWindowEx(hwnd, - (OldX - Buff->ShowX) * GuiData->CharWidth, - (OldY - Buff->ShowY) * GuiData->CharHeight, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); + if (old_pos != sInfo.nPos) + { + USHORT OldX = Buff->ShowX; + USHORT OldY = Buff->ShowY; + *pShowXY = sInfo.nPos; - sInfo.fMask = SIF_POS; - SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); + ScrollWindowEx(hwnd, + (OldX - Buff->ShowX) * GuiData->CharWidth, + (OldY - Buff->ShowY) * GuiData->CharHeight, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); - UpdateWindow(hwnd); - } - return 0; + sInfo.fMask = SIF_POS; + SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); + + UpdateWindow(hwnd); + } + return 0; } static LRESULT CALLBACK GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT Result = 0; - PGUI_CONSOLE_DATA GuiData = NULL; - PCSRSS_CONSOLE Console = NULL; + LRESULT Result = 0; + PGUI_CONSOLE_DATA GuiData = NULL; + PCSRSS_CONSOLE Console = NULL; - GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); - switch(msg) + switch(msg) { - case WM_NCCREATE: + case WM_NCCREATE: Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam); break; - case WM_PAINT: + case WM_PAINT: GuiConsoleHandlePaint(hWnd, (HDC)wParam); break; - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + case WM_CHAR: GuiConsoleHandleKey(hWnd, msg, wParam, lParam); break; - case WM_TIMER: + case WM_TIMER: GuiConsoleHandleTimer(hWnd); break; - case WM_CLOSE: + case WM_CLOSE: GuiConsoleHandleClose(hWnd); break; - case WM_NCDESTROY: + case WM_NCDESTROY: GuiConsoleHandleNcDestroy(hWnd); break; - case WM_LBUTTONDOWN: - GuiConsoleLeftMouseDown(hWnd, lParam); + case WM_LBUTTONDOWN: + GuiConsoleLeftMouseDown(hWnd, lParam); break; - case WM_LBUTTONUP: - GuiConsoleLeftMouseUp(hWnd, lParam); + case WM_LBUTTONUP: + GuiConsoleLeftMouseUp(hWnd, lParam); break; - case WM_RBUTTONDOWN: - GuiConsoleRightMouseDown(hWnd); + case WM_RBUTTONDOWN: + GuiConsoleRightMouseDown(hWnd); break; - case WM_MOUSEMOVE: - GuiConsoleMouseMove(hWnd, wParam, lParam); + case WM_MOUSEMOVE: + GuiConsoleMouseMove(hWnd, wParam, lParam); break; - case WM_SYSCOMMAND: - Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); - break; - case WM_HSCROLL: - case WM_VSCROLL: - Result = GuiConsoleHandleScroll(hWnd, msg, wParam); - break; - case WM_GETMINMAXINFO: - GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam); - break; - case WM_SIZE: - GuiConsoleResize(hWnd, wParam, lParam); - break; - case PM_APPLY_CONSOLE_INFO: - GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); - if (lParam) - { - GuiConsoleWriteUserSettings(Console, GuiData); - } - break; - default: + case WM_SYSCOMMAND: + Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); + break; + case WM_HSCROLL: + case WM_VSCROLL: + Result = GuiConsoleHandleScroll(hWnd, msg, wParam); + break; + case WM_GETMINMAXINFO: + GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam); + break; + case WM_SIZE: + GuiConsoleResize(hWnd, wParam, lParam); + break; + case PM_APPLY_CONSOLE_INFO: + GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); + if (lParam) + { + GuiConsoleWriteUserSettings(Console, GuiData); + } + break; + default: Result = DefWindowProcW(hWnd, msg, wParam, lParam); break; } - return Result; + return Result; } static LRESULT CALLBACK GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - HWND NewWindow; - LONG WindowCount; - MSG Msg; - PWCHAR Buffer, Title; - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; + HWND NewWindow; + LONG WindowCount; + MSG Msg; + PWCHAR Buffer, Title; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; - switch(msg) + switch(msg) { - case WM_CREATE: + case WM_CREATE: SetWindowLongW(hWnd, GWL_USERDATA, 0); return 0; - case PM_CREATE_CONSOLE: + case PM_CREATE_CONSOLE: Buffer = HeapAlloc(Win32CsrApiHeap, 0, Console->Title.Length + sizeof(WCHAR)); if (NULL != Buffer) - { + { memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; Title = Buffer; - } + } else - { + { Title = L""; - } + } NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE, L"ConsoleWindowClass", Title, @@ -2064,38 +1965,41 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) (HINSTANCE) GetModuleHandleW(NULL), (PVOID) Console); if (NULL != Buffer) - { + { HeapFree(Win32CsrApiHeap, 0, Buffer); - } + } if (NULL != NewWindow) - { + { SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); - ShowWindow(NewWindow, SW_SHOW); - } + if (wParam) + { + ShowWindow(NewWindow, SW_SHOW); + } + } return (LRESULT) NewWindow; - case PM_DESTROY_CONSOLE: + case PM_DESTROY_CONSOLE: /* Window creation is done using a PostMessage(), so it's possible that the * window that we want to destroy doesn't exist yet. So first empty the message * queue */ while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) - { + { TranslateMessage(&Msg); DispatchMessageW(&Msg); - } + } DestroyWindow(Console->hWindow); Console->hWindow = NULL; WindowCount = GetWindowLongW(hWnd, GWL_USERDATA); WindowCount--; SetWindowLongW(hWnd, GWL_USERDATA, WindowCount); if (0 == WindowCount) - { + { NotifyWnd = NULL; DestroyWindow(hWnd); PrivateCsrssManualGuiCheck(-1); PostQuitMessage(0); - } + } return 0; - default: + default: return DefWindowProcW(hWnd, msg, wParam, lParam); } } @@ -2103,209 +2007,209 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) static DWORD WINAPI GuiConsoleGuiThread(PVOID Data) { - MSG msg; - PHANDLE GraphicsStartupEvent = (PHANDLE) Data; + MSG msg; + PHANDLE GraphicsStartupEvent = (PHANDLE) Data; - NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", - L"", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - NULL, - NULL, - (HINSTANCE) GetModuleHandleW(NULL), - NULL); - if (NULL == NotifyWnd) + NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", + L"", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + (HINSTANCE) GetModuleHandleW(NULL), + NULL); + if (NULL == NotifyWnd) { - PrivateCsrssManualGuiCheck(-1); - SetEvent(*GraphicsStartupEvent); - return 1; + PrivateCsrssManualGuiCheck(-1); + SetEvent(*GraphicsStartupEvent); + return 1; } - SetEvent(*GraphicsStartupEvent); + SetEvent(*GraphicsStartupEvent); - while(GetMessageW(&msg, NULL, 0, 0)) + while(GetMessageW(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); + TranslateMessage(&msg); + DispatchMessageW(&msg); } - return 1; + return 1; } -static BOOL FASTCALL +static BOOL GuiInit(VOID) { - WNDCLASSEXW wc; + WNDCLASSEXW wc; - if (NULL == NotifyWnd) + if (NULL == NotifyWnd) { - PrivateCsrssManualGuiCheck(+1); + PrivateCsrssManualGuiCheck(+1); } - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"Win32CsrCreateNotify"; - wc.lpfnWndProc = GuiConsoleNotifyWndProc; - wc.style = 0; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIconSm = NULL; - if (RegisterClassExW(&wc) == 0) + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"Win32CsrCreateNotify"; + wc.lpfnWndProc = GuiConsoleNotifyWndProc; + wc.style = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIconSm = NULL; + if (RegisterClassExW(&wc) == 0) { - DPRINT1("Failed to register notify wndproc\n"); - return FALSE; + DPRINT1("Failed to register notify wndproc\n"); + return FALSE; } - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"ConsoleWindowClass"; - wc.lpfnWndProc = GuiConsoleWndProc; - wc.style = 0; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); - wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); - wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), - LR_SHARED); - if (RegisterClassExW(&wc) == 0) + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"ConsoleWindowClass"; + wc.lpfnWndProc = GuiConsoleWndProc; + wc.style = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); + wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); + wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), + LR_SHARED); + if (RegisterClassExW(&wc) == 0) { - DPRINT1("Failed to register console wndproc\n"); - return FALSE; + DPRINT1("Failed to register console wndproc\n"); + return FALSE; } - return TRUE; + return TRUE; } static VOID WINAPI GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = DEFAULT_ATTRIB; + Buffer->DefaultAttrib = DEFAULT_ATTRIB; } static BOOL WINAPI GuiChangeTitle(PCSRSS_CONSOLE Console) { - PWCHAR Buffer, Title; + PWCHAR Buffer, Title; - Buffer = HeapAlloc(Win32CsrApiHeap, 0, - Console->Title.Length + sizeof(WCHAR)); - if (NULL != Buffer) + Buffer = HeapAlloc(Win32CsrApiHeap, 0, + Console->Title.Length + sizeof(WCHAR)); + if (NULL != Buffer) { - memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); - Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; - Title = Buffer; + memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); + Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; + Title = Buffer; } - else + else { - Title = L""; + Title = L""; } - SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); + SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); - if (NULL != Buffer) + if (NULL != Buffer) { - HeapFree(Win32CsrApiHeap, 0, Buffer); + HeapFree(Win32CsrApiHeap, 0, Buffer); } - return TRUE; + return TRUE; } static BOOL WINAPI GuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon) { - SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); - SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); + SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); + SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); - return TRUE; + return TRUE; } static VOID WINAPI GuiCleanupConsole(PCSRSS_CONSOLE Console) { - SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); + SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); } static CSRSS_CONSOLE_VTBL GuiVtbl = { - GuiInitScreenBuffer, - GuiWriteStream, - GuiDrawRegion, - GuiSetCursorInfo, - GuiSetScreenInfo, - GuiUpdateScreenInfo, - GuiChangeTitle, - GuiCleanupConsole, - GuiChangeIcon, - GuiResizeBuffer, + GuiInitScreenBuffer, + GuiWriteStream, + GuiDrawRegion, + GuiSetCursorInfo, + GuiSetScreenInfo, + GuiUpdateScreenInfo, + GuiChangeTitle, + GuiCleanupConsole, + GuiChangeIcon, + GuiResizeBuffer, }; NTSTATUS FASTCALL -GuiInitConsole(PCSRSS_CONSOLE Console) +GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible) { - HANDLE GraphicsStartupEvent; - HANDLE ThreadHandle; - PGUI_CONSOLE_DATA GuiData; + HANDLE GraphicsStartupEvent; + HANDLE ThreadHandle; + PGUI_CONSOLE_DATA GuiData; - if (! ConsInitialized) + if (! ConsInitialized) { - ConsInitialized = TRUE; - if (! GuiInit()) + ConsInitialized = TRUE; + if (! GuiInit()) { - ConsInitialized = FALSE; - return STATUS_UNSUCCESSFUL; + ConsInitialized = FALSE; + return STATUS_UNSUCCESSFUL; } } - Console->Vtbl = &GuiVtbl; - if (NULL == NotifyWnd) + Console->Vtbl = &GuiVtbl; + if (NULL == NotifyWnd) { - GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - if (NULL == GraphicsStartupEvent) + GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if (NULL == GraphicsStartupEvent) { - return STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; } - ThreadHandle = CreateThread(NULL, - 0, - GuiConsoleGuiThread, - (PVOID) &GraphicsStartupEvent, - 0, - NULL); - if (NULL == ThreadHandle) + ThreadHandle = CreateThread(NULL, + 0, + GuiConsoleGuiThread, + (PVOID) &GraphicsStartupEvent, + 0, + NULL); + if (NULL == ThreadHandle) { - NtClose(GraphicsStartupEvent); - DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); - return STATUS_UNSUCCESSFUL; + NtClose(GraphicsStartupEvent); + DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); + return STATUS_UNSUCCESSFUL; } - SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); - CloseHandle(ThreadHandle); + SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); + CloseHandle(ThreadHandle); - WaitForSingleObject(GraphicsStartupEvent, INFINITE); - CloseHandle(GraphicsStartupEvent); + WaitForSingleObject(GraphicsStartupEvent, INFINITE); + CloseHandle(GraphicsStartupEvent); - if (NULL == NotifyWnd) + if (NULL == NotifyWnd) { - DPRINT1("Win32Csr: Failed to create notification window.\n"); - return STATUS_UNSUCCESSFUL; + DPRINT1("Win32Csr: Failed to create notification window.\n"); + return STATUS_UNSUCCESSFUL; } } GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA)); if (!GuiData) - { + { DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n"); return STATUS_UNSUCCESSFUL; - } + } Console->PrivateData = (PVOID) GuiData; /* @@ -2317,7 +2221,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console) */ GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); /* create console */ - PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console); + PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, Visible, (LPARAM) Console); /* wait untill initialization has finished */ WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); @@ -2325,7 +2229,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console) CloseHandle(GuiData->hGuiInitEvent); GuiData->hGuiInitEvent = NULL; - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /* EOF */ diff --git a/subsystems/win32/csrss/win32csr/guiconsole.h b/subsystems/win32/csrss/win32csr/guiconsole.h index 072ef8c8886..705fbba0d92 100644 --- a/subsystems/win32/csrss/win32csr/guiconsole.h +++ b/subsystems/win32/csrss/win32csr/guiconsole.h @@ -13,6 +13,6 @@ #define CONGUI_UPDATE_TIME 0 #define CONGUI_UPDATE_TIMER 1 -NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console); +NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible); /*EOF*/ diff --git a/subsystems/win32/csrss/win32csr/handle.c b/subsystems/win32/csrss/win32csr/handle.c new file mode 100644 index 00000000000..ce8db451681 --- /dev/null +++ b/subsystems/win32/csrss/win32csr/handle.c @@ -0,0 +1,395 @@ +/* $Id$ + * + * reactos/subsys/csrss/api/handle.c + * + * CSRSS handle functions + * + * ReactOS Operating System + */ + +/* INCLUDES ******************************************************************/ + +#include + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +static +BOOL +CsrIsConsoleHandle(HANDLE Handle) +{ + return ((ULONG_PTR)Handle & 0x10000003) == 0x3; +} + +static INT +AdjustHandleCounts(PCSRSS_HANDLE Entry, INT Change) +{ + Object_t *Object = Entry->Object; + if (Entry->Access & GENERIC_READ) Object->AccessRead += Change; + if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change; + if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change; + if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change; + Object->HandleCount += Change; + return Object->HandleCount; +} + +static VOID +Win32CsrCreateHandleEntry( + PCSRSS_HANDLE Entry) +{ + Object_t *Object = Entry->Object; + EnterCriticalSection(&Object->Console->Lock); + AdjustHandleCounts(Entry, +1); + LeaveCriticalSection(&Object->Console->Lock); +} + +static VOID +Win32CsrCloseHandleEntry( + PCSRSS_HANDLE Entry) +{ + Object_t *Object = Entry->Object; + if (Object != NULL) + { + PCSRSS_CONSOLE Console = Object->Console; + EnterCriticalSection(&Console->Lock); + /* If the last handle to a screen buffer is closed, delete it */ + if (AdjustHandleCounts(Entry, -1) == 0 + && Object->Type == CONIO_SCREEN_BUFFER_MAGIC) + { + PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object; + /* ...unless it's the only buffer left. Windows allows deletion + * even of the last buffer, but having to deal with a lack of + * any active buffer might be error-prone. */ + if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) + ConioDeleteScreenBuffer(Buffer); + } + LeaveCriticalSection(&Console->Lock); + Entry->Object = NULL; + } +} + +NTSTATUS +FASTCALL +Win32CsrReleaseObject( + PCSRSS_PROCESS_DATA ProcessData, + HANDLE Handle) +{ + ULONG_PTR h = (ULONG_PTR)Handle >> 2; + Object_t *Object; + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (h >= ProcessData->HandleTableSize + || (Object = ProcessData->HandleTable[h].Object) == NULL) + { + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; + } + Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_SUCCESS; +} + +NTSTATUS +FASTCALL +Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, + HANDLE Handle, + Object_t **Object, + DWORD Access, + LONG Type) +{ + ULONG_PTR h = (ULONG_PTR)Handle >> 2; + + DPRINT("CsrGetObject, Object: %x, %x, %x\n", + Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize + || (*Object = ProcessData->HandleTable[h].Object) == NULL + || ~ProcessData->HandleTable[h].Access & Access + || (Type != 0 && (*Object)->Type != Type)) + { + DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; + } + _InterlockedIncrement(&(*Object)->Console->ReferenceCount); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + + EnterCriticalSection(&((*Object)->Console->Lock)); + return STATUS_SUCCESS; +} + +VOID +FASTCALL +Win32CsrUnlockObject(Object_t *Object) +{ + PCSRSS_CONSOLE Console = Object->Console; + LeaveCriticalSection(&Console->Lock); + /* dec ref count */ + if (_InterlockedDecrement(&Console->ReferenceCount) == 0) + ConioDeleteConsole(&Console->Header); +} + +NTSTATUS +WINAPI +Win32CsrReleaseConsole( + PCSRSS_PROCESS_DATA ProcessData) +{ + PCSRSS_CONSOLE Console; + ULONG i; + + /* Close all console handles and detach process from console */ + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + + for (i = 0; i < ProcessData->HandleTableSize; i++) + Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]); + ProcessData->HandleTableSize = 0; + RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable); + ProcessData->HandleTable = NULL; + + Console = ProcessData->Console; + if (Console != NULL) + { + ProcessData->Console = NULL; + EnterCriticalSection(&Console->Lock); + RemoveEntryList(&ProcessData->ProcessEntry); + LeaveCriticalSection(&Console->Lock); + if (_InterlockedDecrement(&Console->ReferenceCount) == 0) + ConioDeleteConsole(&Console->Header); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_SUCCESS; + } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_PARAMETER; +} + +NTSTATUS +FASTCALL +Win32CsrInsertObject( + PCSRSS_PROCESS_DATA ProcessData, + PHANDLE Handle, + Object_t *Object, + DWORD Access, + BOOL Inheritable, + DWORD ShareMode) +{ + ULONG i; + PCSRSS_HANDLE Block; + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + + for (i = 0; i < ProcessData->HandleTableSize; i++) + { + if (ProcessData->HandleTable[i].Object == NULL) + { + break; + } + } + if (i >= ProcessData->HandleTableSize) + { + Block = RtlAllocateHeap(Win32CsrApiHeap, + HEAP_ZERO_MEMORY, + (ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE)); + if (Block == NULL) + { + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return(STATUS_UNSUCCESSFUL); + } + RtlCopyMemory(Block, + ProcessData->HandleTable, + ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE)); + RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable); + ProcessData->HandleTable = Block; + ProcessData->HandleTableSize += 64; + } + ProcessData->HandleTable[i].Object = Object; + ProcessData->HandleTable[i].Access = Access; + ProcessData->HandleTable[i].Inheritable = Inheritable; + ProcessData->HandleTable[i].ShareMode = ShareMode; + Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]); + *Handle = UlongToHandle((i << 2) | 0x3); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return(STATUS_SUCCESS); +} + +NTSTATUS +WINAPI +Win32CsrDuplicateHandleTable( + PCSRSS_PROCESS_DATA SourceProcessData, + PCSRSS_PROCESS_DATA TargetProcessData) +{ + ULONG i; + + if (TargetProcessData->HandleTableSize) + { + return STATUS_INVALID_PARAMETER; + } + + RtlEnterCriticalSection(&SourceProcessData->HandleTableLock); + + /* we are called from CreateProcessData, it isn't necessary to lock the target process data */ + + TargetProcessData->HandleTable = RtlAllocateHeap(Win32CsrApiHeap, + HEAP_ZERO_MEMORY, + SourceProcessData->HandleTableSize + * sizeof(CSRSS_HANDLE)); + if (TargetProcessData->HandleTable == NULL) + { + RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); + return(STATUS_UNSUCCESSFUL); + } + TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize; + for (i = 0; i < SourceProcessData->HandleTableSize; i++) + { + if (SourceProcessData->HandleTable[i].Object != NULL && + SourceProcessData->HandleTable[i].Inheritable) + { + TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i]; + Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]); + } + } + RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); + return(STATUS_SUCCESS); +} + +CSR_API(CsrGetHandle) +{ + NTSTATUS Status = STATUS_SUCCESS; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Request->Data.GetInputHandleRequest.Handle = INVALID_HANDLE_VALUE; + + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (ProcessData->Console) + { + DWORD DesiredAccess = Request->Data.GetInputHandleRequest.Access; + DWORD ShareMode = Request->Data.GetInputHandleRequest.ShareMode; + + PCSRSS_CONSOLE Console = ProcessData->Console; + Object_t *Object; + + EnterCriticalSection(&Console->Lock); + if (Request->Type == GET_OUTPUT_HANDLE) + Object = &Console->ActiveBuffer->Header; + else + Object = &Console->Header; + + if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0) || + ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) || + (!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0) || + (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0)) + { + DPRINT1("Sharing violation\n"); + Status = STATUS_SHARING_VIOLATION; + } + else + { + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.GetInputHandleRequest.Handle, + Object, + DesiredAccess, + Request->Data.GetInputHandleRequest.Inheritable, + ShareMode); + } + LeaveCriticalSection(&Console->Lock); + } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + + return Status; +} + +CSR_API(CsrCloseHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + return Win32CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); +} + +CSR_API(CsrVerifyHandle) +{ + ULONG_PTR Index; + NTSTATUS Status = STATUS_SUCCESS; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Index = (ULONG_PTR)Request->Data.VerifyHandleRequest.Handle >> 2; + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (Index >= ProcessData->HandleTableSize || + ProcessData->HandleTable[Index].Object == NULL) + { + DPRINT("CsrVerifyObject failed\n"); + Status = STATUS_INVALID_HANDLE; + } + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + + return Status; +} + +CSR_API(CsrDuplicateHandle) +{ + ULONG_PTR Index; + PCSRSS_HANDLE Entry; + DWORD DesiredAccess; + + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Index = (ULONG_PTR)Request->Data.DuplicateHandleRequest.Handle >> 2; + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + if (Index >= ProcessData->HandleTableSize + || (Entry = &ProcessData->HandleTable[Index])->Object == NULL) + { + DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_HANDLE; + } + + if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS) + { + DesiredAccess = Entry->Access; + } + else + { + DesiredAccess = Request->Data.DuplicateHandleRequest.Access; + /* Make sure the source handle has all the desired flags */ + if (~Entry->Access & DesiredAccess) + { + DPRINT1("Handle %p only has access %X; requested %X\n", + Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return STATUS_INVALID_PARAMETER; + } + } + + Request->Status = Win32CsrInsertObject(ProcessData, + &Request->Data.DuplicateHandleRequest.Handle, + Entry->Object, + DesiredAccess, + Request->Data.DuplicateHandleRequest.Inheritable, + Entry->ShareMode); + if (NT_SUCCESS(Request->Status) + && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) + { + Win32CsrCloseHandleEntry(Entry); + } + + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Request->Status; +} + +CSR_API(CsrGetInputWaitHandle) +{ + Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); + Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + + Request->Data.GetConsoleInputWaitHandle.InputWaitHandle = ProcessData->ConsoleEvent; + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/harderror.c b/subsystems/win32/csrss/win32csr/harderror.c index 4b46e340842..0e10aad8a9d 100644 --- a/subsystems/win32/csrss/win32csr/harderror.c +++ b/subsystems/win32/csrss/win32csr/harderror.c @@ -84,8 +84,8 @@ CsrpGetClientFileName( ClientFileNameU->MaximumLength = ModuleData.BaseDllName.MaximumLength; ClientFileNameU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - ClientFileNameU->MaximumLength); + HEAP_ZERO_MEMORY, + ClientFileNameU->MaximumLength); Status = NtReadVirtualMemory(hProcess, ModuleData.BaseDllName.Buffer, @@ -123,9 +123,9 @@ CsrpCaptureStringParameters( UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask; /* Read all strings from client space */ - for (nParam = 0; - nParam < HardErrorMessage->NumberOfParameters; - nParam++, UnicodeStringParameterMask >>= 1) + for (nParam = 0; + nParam < HardErrorMessage->NumberOfParameters; + nParam++, UnicodeStringParameterMask >>= 1) { Parameters[nParam] = 0; @@ -194,9 +194,9 @@ CsrpFreeStringParameters( UnicodeStringParameterMask = HardErrorMessage->UnicodeStringParameterMask; /* Loop all parameters */ - for (nParam = 0; - nParam < HardErrorMessage->NumberOfParameters; - nParam++, UnicodeStringParameterMask >>= 1) + for (nParam = 0; + nParam < HardErrorMessage->NumberOfParameters; + nParam++, UnicodeStringParameterMask >>= 1) { /* Check if the current parameter is a string */ if (UnicodeStringParameterMask & 0x01) @@ -292,8 +292,8 @@ CsrpFormatMessages( /* Allocate a buffer for the caption */ CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - CaptionStringU->MaximumLength); + HEAP_ZERO_MEMORY, + CaptionStringU->MaximumLength); /* Append the file name, seperator and the caption text */ CaptionStringU->Length = 0; @@ -383,13 +383,13 @@ CsrpFormatMessages( { /* Print the string into the buffer */ StringCbPrintfW(TextStringU->Buffer, - TextStringU->MaximumLength, - FormatString, - Parameters[0], - Parameters[1], - Parameters[2], - Parameters[3], - Parameters[4]); + TextStringU->MaximumLength, + FormatString, + Parameters[0], + Parameters[1], + Parameters[2], + Parameters[3], + Parameters[4]); Status = STATUS_SUCCESS; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -424,30 +424,30 @@ CsrpMessageBox( /* Set the message box type */ switch (ValidResponseOptions) { - case OptionAbortRetryIgnore: - Type = MB_ABORTRETRYIGNORE; - break; - case OptionOk: - Type = MB_OK; - break; - case OptionOkCancel: - Type = MB_OKCANCEL; - break; - case OptionRetryCancel: - Type = MB_RETRYCANCEL; - break; - case OptionYesNo: - Type = MB_YESNO; - break; - case OptionYesNoCancel: - Type = MB_YESNOCANCEL; - break; - case OptionShutdownSystem: - Type = MB_RETRYCANCEL; // FIXME??? - break; + case OptionAbortRetryIgnore: + Type = MB_ABORTRETRYIGNORE; + break; + case OptionOk: + Type = MB_OK; + break; + case OptionOkCancel: + Type = MB_OKCANCEL; + break; + case OptionRetryCancel: + Type = MB_RETRYCANCEL; + break; + case OptionYesNo: + Type = MB_YESNO; + break; + case OptionYesNoCancel: + Type = MB_YESNOCANCEL; + break; + case OptionShutdownSystem: + Type = MB_RETRYCANCEL; // FIXME??? + break; /* Anything else is invalid */ - default: - return ResponseNotHandled; + default: + return ResponseNotHandled; } /* Set severity */ @@ -457,7 +457,7 @@ CsrpMessageBox( Type |= MB_SYSTEMMODAL | MB_SETFOREGROUND; - DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n", + DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n", Text, Caption, Severity, Type); /* Display a message box */ @@ -466,15 +466,15 @@ CsrpMessageBox( /* Return response value */ switch (MessageBoxResponse) { - case IDOK: return ResponseOk; - case IDCANCEL: return ResponseCancel; - case IDYES: return ResponseYes; - case IDNO: return ResponseNo; - case IDABORT: return ResponseAbort; - case IDIGNORE: return ResponseIgnore; - case IDRETRY: return ResponseRetry; - case IDTRYAGAIN: return ResponseTryAgain; - case IDCONTINUE: return ResponseContinue; + case IDOK: return ResponseOk; + case IDCANCEL: return ResponseCancel; + case IDYES: return ResponseYes; + case IDNO: return ResponseNo; + case IDABORT: return ResponseAbort; + case IDIGNORE: return ResponseIgnore; + case IDRETRY: return ResponseRetry; + case IDTRYAGAIN: return ResponseTryAgain; + case IDCONTINUE: return ResponseContinue; } return ResponseNotHandled; @@ -537,7 +537,7 @@ Win32CsrHardError( if (!NT_SUCCESS(Status)) { - return FALSE; + return FALSE; } /* Display the message box */ diff --git a/subsystems/win32/csrss/win32csr/lang/it-IT.rc b/subsystems/win32/csrss/win32csr/lang/it-IT.rc index 4aecce782f1..21d87610dc5 100644 --- a/subsystems/win32/csrss/win32csr/lang/it-IT.rc +++ b/subsystems/win32/csrss/win32csr/lang/it-IT.rc @@ -11,10 +11,10 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Fine del programma - " +CAPTION "Arresto del programma - " FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Fine del programma... Attendere",IDC_STATIC,7,7,186,11 + LTEXT "Arresto del programma... Attendere",IDC_STATIC,7,7,186,11 CONTROL "Progresso",IDC_PROGRESS,"msctls_progress32",WS_BORDER, 7,20,186,13 LTEXT "Se si sceglie di terminare il programma immediatamente, si perderanno tutti i dati non salvati. Per terminare il programma ora, selezionare Termina ora.", @@ -24,7 +24,7 @@ END IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "End Program - " +CAPTION "Arresto del programma - " FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "Annulla",IDCANCEL,142,98,43,17 diff --git a/subsystems/win32/csrss/win32csr/lineinput.c b/subsystems/win32/csrss/win32csr/lineinput.c new file mode 100644 index 00000000000..957cb07cbfe --- /dev/null +++ b/subsystems/win32/csrss/win32csr/lineinput.c @@ -0,0 +1,574 @@ +/* + * PROJECT: ReactOS CSRSS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: subsystems/win32/csrss/win32csr/lineinput.c + * PURPOSE: Console line input functions + * PROGRAMMERS: Jeffrey Morlan + */ + +/* INCLUDES ******************************************************************/ + +#define NDEBUG +#include "w32csr.h" +#include + +typedef struct tagHISTORY_BUFFER +{ + LIST_ENTRY ListEntry; + WORD Position; + WORD MaxEntries; + WORD NumEntries; + PUNICODE_STRING Entries; + UNICODE_STRING ExeName; +} HISTORY_BUFFER, *PHISTORY_BUFFER; + +/* FUNCTIONS *****************************************************************/ + +static PHISTORY_BUFFER +HistoryCurrentBuffer(PCSRSS_CONSOLE Console) +{ + /* TODO: use actual EXE name sent from process that called ReadConsole */ + UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" }; + PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; + PHISTORY_BUFFER Hist; + + for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink) + { + Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); + if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE)) + return Hist; + } + + /* Couldn't find the buffer, create a new one */ + Hist = HeapAlloc(Win32CsrApiHeap, 0, sizeof(HISTORY_BUFFER) + ExeName.Length); + if (!Hist) + return NULL; + Hist->MaxEntries = Console->HistoryBufferSize; + Hist->NumEntries = 0; + Hist->Entries = HeapAlloc(Win32CsrApiHeap, 0, Hist->MaxEntries * sizeof(UNICODE_STRING)); + if (!Hist->Entries) + { + HeapFree(Win32CsrApiHeap, 0, Hist); + return NULL; + } + Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length; + Hist->ExeName.Buffer = (PWCHAR)(Hist + 1); + memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length); + InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry); + return Hist; +} + +static VOID +HistoryAddEntry(PCSRSS_CONSOLE Console) +{ + UNICODE_STRING NewEntry; + PHISTORY_BUFFER Hist; + INT i; + + NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR); + NewEntry.Buffer = Console->LineBuffer; + + if (!(Hist = HistoryCurrentBuffer(Console))) + return; + + /* Don't add blank or duplicate entries */ + if (NewEntry.Length == 0 || Hist->MaxEntries == 0 || + (Hist->NumEntries > 0 && + RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE))) + { + return; + } + + if (Console->HistoryNoDup) + { + /* Check if this line has been entered before */ + for (i = Hist->NumEntries - 1; i >= 0; i--) + { + if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE)) + { + /* Just rotate the list to bring this entry to the end */ + NewEntry = Hist->Entries[i]; + memmove(&Hist->Entries[i], &Hist->Entries[i + 1], + (Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING)); + Hist->Entries[Hist->NumEntries - 1] = NewEntry; + Hist->Position = Hist->NumEntries - 1; + return; + } + } + } + + if (Hist->NumEntries == Hist->MaxEntries) + { + /* List is full, remove oldest entry */ + RtlFreeUnicodeString(&Hist->Entries[0]); + memmove(&Hist->Entries[0], &Hist->Entries[1], + --Hist->NumEntries * sizeof(UNICODE_STRING)); + } + + if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries]))) + Hist->NumEntries++; + Hist->Position = Hist->NumEntries - 1; +} + +static VOID +HistoryGetCurrentEntry(PCSRSS_CONSOLE Console, PUNICODE_STRING Entry) +{ + PHISTORY_BUFFER Hist; + if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0) + Entry->Length = 0; + else + *Entry = Hist->Entries[Hist->Position]; +} + +static PHISTORY_BUFFER +HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName) +{ + PLIST_ENTRY Entry = Console->HistoryBuffers.Flink; + while (Entry != &Console->HistoryBuffers) + { + /* For the history APIs, the caller is allowed to give only part of the name */ + PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry); + if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE)) + return Hist; + Entry = Entry->Flink; + } + return NULL; +} + +VOID FASTCALL +HistoryDeleteBuffer(PHISTORY_BUFFER Hist) +{ + if (!Hist) + return; + while (Hist->NumEntries != 0) + RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]); + HeapFree(Win32CsrApiHeap, 0, Hist->Entries); + RemoveEntryList(&Hist->ListEntry); + HeapFree(Win32CsrApiHeap, 0, Hist); +} + +CSR_API(CsrGetCommandHistoryLength) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + PHISTORY_BUFFER Hist; + ULONG Length = 0; + INT i; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.GetCommandHistoryLength.ExeName.Buffer, + Request->Data.GetCommandHistoryLength.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); + if (Hist) + { + for (i = 0; i < Hist->NumEntries; i++) + Length += Hist->Entries[i].Length + sizeof(WCHAR); + } + Request->Data.GetCommandHistoryLength.Length = Length; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrGetCommandHistory) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + PHISTORY_BUFFER Hist; + PBYTE Buffer = (PBYTE)Request->Data.GetCommandHistory.History; + ULONG BufferSize = Request->Data.GetCommandHistory.Length; + INT i; + + if (!Win32CsrValidateBuffer(ProcessData, Buffer, BufferSize, 1) || + !Win32CsrValidateBuffer(ProcessData, + Request->Data.GetCommandHistory.ExeName.Buffer, + Request->Data.GetCommandHistory.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName); + if (Hist) + { + for (i = 0; i < Hist->NumEntries; i++) + { + if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR))) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length); + Buffer += Hist->Entries[i].Length; + *(PWCHAR)Buffer = L'\0'; + Buffer += sizeof(WCHAR); + } + } + Request->Data.GetCommandHistory.Length = Buffer - (PBYTE)Request->Data.GetCommandHistory.History; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrExpungeCommandHistory) +{ + PCSRSS_CONSOLE Console; + PHISTORY_BUFFER Hist; + NTSTATUS Status; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.ExpungeCommandHistory.ExeName.Buffer, + Request->Data.ExpungeCommandHistory.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.ExpungeCommandHistory.ExeName); + HistoryDeleteBuffer(Hist); + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrSetHistoryNumberCommands) +{ + PCSRSS_CONSOLE Console; + PHISTORY_BUFFER Hist; + NTSTATUS Status; + WORD MaxEntries = Request->Data.SetHistoryNumberCommands.NumCommands; + PUNICODE_STRING OldEntryList, NewEntryList; + + if (!Win32CsrValidateBuffer(ProcessData, + Request->Data.SetHistoryNumberCommands.ExeName.Buffer, + Request->Data.SetHistoryNumberCommands.ExeName.Length, 1)) + { + return STATUS_ACCESS_VIOLATION; + } + + Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Hist = HistoryFindBuffer(Console, &Request->Data.SetHistoryNumberCommands.ExeName); + if (Hist) + { + OldEntryList = Hist->Entries; + NewEntryList = HeapAlloc(Win32CsrApiHeap, 0, + MaxEntries * sizeof(UNICODE_STRING)); + if (!NewEntryList) + { + Status = STATUS_NO_MEMORY; + } + else + { + /* If necessary, shrink by removing oldest entries */ + for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--) + { + RtlFreeUnicodeString(Hist->Entries++); + Hist->Position += (Hist->Position == 0); + } + + Hist->MaxEntries = MaxEntries; + Hist->Entries = memcpy(NewEntryList, Hist->Entries, + Hist->NumEntries * sizeof(UNICODE_STRING)); + HeapFree(Win32CsrApiHeap, 0, OldEntryList); + } + } + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrGetHistoryInfo) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Request->Data.SetHistoryInfo.HistoryBufferSize = Console->HistoryBufferSize; + Request->Data.SetHistoryInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; + Request->Data.SetHistoryInfo.dwFlags = Console->HistoryNoDup; + ConioUnlockConsole(Console); + } + return Status; +} + +CSR_API(CsrSetHistoryInfo) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console); + if (NT_SUCCESS(Status)) + { + Console->HistoryBufferSize = (WORD)Request->Data.SetHistoryInfo.HistoryBufferSize; + Console->NumberOfHistoryBuffers = (WORD)Request->Data.SetHistoryInfo.NumberOfHistoryBuffers; + Console->HistoryNoDup = Request->Data.SetHistoryInfo.dwFlags & HISTORY_NO_DUP_FLAG; + ConioUnlockConsole(Console); + } + return Status; +} + +static VOID +LineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos) +{ + if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT) + { + PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + UINT OldCursorX = Buffer->CurrentX; + UINT OldCursorY = Buffer->CurrentY; + INT XY = OldCursorY * Buffer->MaxX + OldCursorX; + + XY += (Pos - Console->LinePos); + if (XY < 0) + XY = 0; + else if (XY >= Buffer->MaxY * Buffer->MaxX) + XY = Buffer->MaxY * Buffer->MaxX - 1; + + Buffer->CurrentX = XY % Buffer->MaxX; + Buffer->CurrentY = XY / Buffer->MaxX; + ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY); + } + + Console->LinePos = Pos; +} + +static VOID +LineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion) +{ + UINT Pos = Console->LinePos; + UINT NewSize = Console->LineSize - NumToDelete + NumToInsert; + INT i; + + /* Make sure there's always enough room for ending \r\n */ + if (NewSize + 2 > Console->LineMaxSize) + return; + + memmove(&Console->LineBuffer[Pos + NumToInsert], + &Console->LineBuffer[Pos + NumToDelete], + (Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR)); + memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR)); + + if (Console->Mode & ENABLE_ECHO_INPUT) + { + for (i = Pos; i < NewSize; i++) + { + CHAR AsciiChar; + WideCharToMultiByte(Console->OutputCodePage, 0, + &Console->LineBuffer[i], 1, + &AsciiChar, 1, NULL, NULL); + ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE); + } + for (; i < Console->LineSize; i++) + { + ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE); + } + Console->LinePos = i; + } + + Console->LineSize = NewSize; + LineInputSetPos(Console, Pos + NumToInsert); +} + +static VOID +LineInputRecallHistory(PCSRSS_CONSOLE Console, INT Offset) +{ + PHISTORY_BUFFER Hist; + + if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0) + return; + + Offset += Hist->Position; + Offset = max(Offset, 0); + Offset = min(Offset, Hist->NumEntries - 1); + Hist->Position = Offset; + + LineInputSetPos(Console, 0); + LineInputEdit(Console, Console->LineSize, + Hist->Entries[Offset].Length / sizeof(WCHAR), + Hist->Entries[Offset].Buffer); +} + +VOID FASTCALL +LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent) +{ + UINT Pos = Console->LinePos; + PHISTORY_BUFFER Hist; + UNICODE_STRING Entry; + INT HistPos; + + switch (KeyEvent->wVirtualKeyCode) + { + case VK_ESCAPE: + /* Clear entire line */ + LineInputSetPos(Console, 0); + LineInputEdit(Console, Console->LineSize, 0, NULL); + return; + case VK_HOME: + /* Move to start of line. With ctrl, erase everything left of cursor */ + LineInputSetPos(Console, 0); + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + LineInputEdit(Console, Pos, 0, NULL); + return; + case VK_END: + /* Move to end of line. With ctrl, erase everything right of cursor */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + LineInputEdit(Console, Console->LineSize - Pos, 0, NULL); + else + LineInputSetPos(Console, Console->LineSize); + return; + case VK_LEFT: + /* Move left. With ctrl, move to beginning of previous word */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--; + while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--; + } + else + { + Pos -= (Pos > 0); + } + LineInputSetPos(Console, Pos); + return; + case VK_RIGHT: + case VK_F1: + /* Move right. With ctrl, move to beginning of next word */ + if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++; + while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++; + LineInputSetPos(Console, Pos); + return; + } + else + { + /* Recall one character (but don't overwrite current line) */ + HistoryGetCurrentEntry(Console, &Entry); + if (Pos < Console->LineSize) + LineInputSetPos(Console, Pos + 1); + else if (Pos * sizeof(WCHAR) < Entry.Length) + LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]); + } + return; + case VK_DELETE: + /* Remove character to right of cursor */ + if (Pos != Console->LineSize) + LineInputEdit(Console, 1, 0, NULL); + return; + case VK_PRIOR: + /* Recall first history entry */ + LineInputRecallHistory(Console, -((WORD)-1)); + return; + case VK_NEXT: + /* Recall last history entry */ + LineInputRecallHistory(Console, +((WORD)-1)); + return; + case VK_UP: + case VK_F5: + /* Recall previous history entry. On first time, actually recall the + * current (usually last) entry; on subsequent times go back. */ + LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0); + Console->LineUpPressed = TRUE; + return; + case VK_DOWN: + /* Recall next history entry */ + LineInputRecallHistory(Console, +1); + return; + case VK_F3: + /* Recall remainder of current history entry */ + HistoryGetCurrentEntry(Console, &Entry); + if (Pos * sizeof(WCHAR) < Entry.Length) + { + UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos); + UINT DeleteSize = min(Console->LineSize - Pos, InsertSize); + LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]); + } + return; + case VK_F6: + /* Insert a ^Z character */ + KeyEvent->uChar.UnicodeChar = 26; + break; + case VK_F7: + if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + HistoryDeleteBuffer(HistoryCurrentBuffer(Console)); + return; + case VK_F8: + /* Search for history entries starting with input. */ + if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0) + return; + + /* Like Up/F5, on first time start from current (usually last) entry, + * but on subsequent times start at previous entry. */ + if (Console->LineUpPressed) + Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1; + Console->LineUpPressed = TRUE; + + Entry.Length = Console->LinePos * sizeof(WCHAR); + Entry.Buffer = Console->LineBuffer; + + /* Keep going backwards, even wrapping around to the end, + * until we get back to starting point */ + HistPos = Hist->Position; + do + { + if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE)) + { + Hist->Position = HistPos; + LineInputEdit(Console, Console->LineSize - Pos, + Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos, + &Hist->Entries[HistPos].Buffer[Pos]); + /* Cursor stays where it was */ + LineInputSetPos(Console, Pos); + return; + } + if (--HistPos < 0) HistPos += Hist->NumEntries; + } while (HistPos != Hist->Position); + return; + } + + if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT) + { + /* backspace handling - if processed input enabled then we handle it here + * otherwise we treat it like a normal char. */ + if (Pos > 0) + { + LineInputSetPos(Console, Pos - 1); + LineInputEdit(Console, 1, 0, NULL); + } + } + else if (KeyEvent->uChar.UnicodeChar == L'\r') + { + HistoryAddEntry(Console); + + /* TODO: Expand aliases */ + + LineInputSetPos(Console, Console->LineSize); + Console->LineBuffer[Console->LineSize++] = L'\r'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE); + if (Console->Mode & ENABLE_PROCESSED_INPUT) + { + Console->LineBuffer[Console->LineSize++] = L'\n'; + if (Console->Mode & ENABLE_ECHO_INPUT) + ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE); + } + Console->LineComplete = TRUE; + Console->LinePos = 0; + } + else if (KeyEvent->uChar.UnicodeChar != L'\0') + { + /* Normal character */ + LineInputEdit(Console, 0, 1, &KeyEvent->uChar.UnicodeChar); + } +} + +/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/tuiconsole.c b/subsystems/win32/csrss/win32csr/tuiconsole.c index 5c03f93d590..f078fe1e2a6 100644 --- a/subsystems/win32/csrss/win32csr/tuiconsole.c +++ b/subsystems/win32/csrss/win32csr/tuiconsole.c @@ -20,15 +20,15 @@ static BOOL ConsInitialized = FALSE; static LRESULT CALLBACK TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_ACTIVATE) + if (msg == WM_ACTIVATE) { - if (LOWORD(wParam) != WA_INACTIVE) + if (LOWORD(wParam) != WA_INACTIVE) { - SetFocus(hWnd); - ConioDrawConsole(ActiveConsole); + SetFocus(hWnd); + ConioDrawConsole(ActiveConsole); } } - return DefWindowProcW(hWnd, msg, wParam, lParam); + return DefWindowProcW(hWnd, msg, wParam, lParam); } static BOOL FASTCALL @@ -63,19 +63,19 @@ cleanup: static BOOL FASTCALL TuiInit(DWORD OemCP) { - CONSOLE_SCREEN_BUFFER_INFO ScrInfo; - DWORD BytesReturned; - WNDCLASSEXW wc; - USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + CONSOLE_SCREEN_BUFFER_INFO ScrInfo; + DWORD BytesReturned; + WNDCLASSEXW wc; + USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - TuiStartService(L"Blue"); + TuiStartService(L"Blue"); - ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL, - OPEN_EXISTING, 0, NULL); - if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) + ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL, + OPEN_EXISTING, 0, NULL); + if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) { - DPRINT1("Failed to open BlueScreen.\n"); - return FALSE; + DPRINT1("Failed to open BlueScreen.\n"); + return FALSE; } if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT, @@ -93,163 +93,163 @@ TuiInit(DWORD OemCP) DPRINT1("Failed to set text attribute\n"); } - ActiveConsole = NULL; - InitializeCriticalSection(&ActiveConsoleLock); - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, - NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) + ActiveConsole = NULL; + InitializeCriticalSection(&ActiveConsoleLock); + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, + NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL)) { - DPRINT1("Failed to get console info\n"); - return FALSE; + DPRINT1("Failed to get console info\n"); + return FALSE; } - PhysicalConsoleSize = ScrInfo.dwSize; + PhysicalConsoleSize = ScrInfo.dwSize; - RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = L"TuiConsoleWindowClass"; - wc.lpfnWndProc = TuiConsoleWndProc; - wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - if (RegisterClassExW(&wc) == 0) + RtlZeroMemory(&wc, sizeof(WNDCLASSEXW)); + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = L"TuiConsoleWindowClass"; + wc.lpfnWndProc = TuiConsoleWndProc; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + if (RegisterClassExW(&wc) == 0) { - DPRINT1("Failed to register console wndproc\n"); - return FALSE; + DPRINT1("Failed to register console wndproc\n"); + return FALSE; } - return TRUE; + return TRUE; } static VOID WINAPI TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) { - Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; } static void FASTCALL -TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, RECT *Region) +TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *Region) { - UINT SrcDelta, DestDelta; - LONG i; - PBYTE Src, SrcEnd; + UINT SrcDelta, DestDelta; + LONG i; + PBYTE Src, SrcEnd; - Src = ConioCoordToPointer(Buff, Region->left, Region->top); - SrcDelta = Buff->MaxX * 2; - SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2; - DestDelta = ConioRectWidth(Region) * 2; - for (i = Region->top; i <= Region->bottom; i++) + Src = ConioCoordToPointer(Buff, Region->Left, Region->Top); + SrcDelta = Buff->MaxX * 2; + SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2; + DestDelta = ConioRectWidth(Region) * 2; + for (i = Region->Top; i <= Region->Bottom; i++) { - memcpy(Dest, Src, DestDelta); - Src += SrcDelta; - if (SrcEnd <= Src) + memcpy(Dest, Src, DestDelta); + Src += SrcDelta; + if (SrcEnd <= Src) { - Src -= Buff->MaxY * Buff->MaxX * 2; + Src -= Buff->MaxY * Buff->MaxX * 2; } - Dest += DestDelta; + Dest += DestDelta; } } static VOID WINAPI -TuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region) +TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) { - DWORD BytesReturned; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - PCONSOLE_DRAW ConsoleDraw; - UINT ConsoleDrawSize; + DWORD BytesReturned; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PCONSOLE_DRAW ConsoleDraw; + UINT ConsoleDrawSize; - if (ActiveConsole != Console) + if (ActiveConsole != Console) { - return; + return; } - ConsoleDrawSize = sizeof(CONSOLE_DRAW) + - (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; - ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize); - if (NULL == ConsoleDraw) + ConsoleDrawSize = sizeof(CONSOLE_DRAW) + + (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; + ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize); + if (NULL == ConsoleDraw) { - DPRINT1("HeapAlloc failed\n"); - return; + DPRINT1("HeapAlloc failed\n"); + return; } - ConsoleDraw->X = Region->left; - ConsoleDraw->Y = Region->top; - ConsoleDraw->SizeX = ConioRectWidth(Region); - ConsoleDraw->SizeY = ConioRectHeight(Region); - ConsoleDraw->CursorX = Buff->CurrentX; - ConsoleDraw->CursorY = Buff->CurrentY; + ConsoleDraw->X = Region->Left; + ConsoleDraw->Y = Region->Top; + ConsoleDraw->SizeX = ConioRectWidth(Region); + ConsoleDraw->SizeY = ConioRectHeight(Region); + ConsoleDraw->CursorX = Buff->CurrentX; + ConsoleDraw->CursorY = Buff->CurrentY; - TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); + TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region); - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, - NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW, + NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL)) { - DPRINT1("Failed to draw console\n"); - HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); - return; + DPRINT1("Failed to draw console\n"); + HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); + return; } - HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); + HeapFree(Win32CsrApiHeap, 0, ConsoleDraw); } static VOID WINAPI -TuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY, +TuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, UINT ScrolledLines, CHAR *Buffer, UINT Length) { - DWORD BytesWritten; - PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; + DWORD BytesWritten; + PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; - if (ActiveConsole->ActiveBuffer != Buff) + if (ActiveConsole->ActiveBuffer != Buff) { - return; + return; } - if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) + if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL)) { - DPRINT1("Error writing to BlueScreen\n"); + DPRINT1("Error writing to BlueScreen\n"); } } static BOOL WINAPI TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) { - DWORD BytesReturned; + DWORD BytesReturned; - if (ActiveConsole->ActiveBuffer != Buff) + if (ActiveConsole->ActiveBuffer != Buff) { - return TRUE; + return TRUE; } - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, - &Buff->CursorInfo, sizeof(Buff->CursorInfo), NULL, 0, - &BytesReturned, NULL)) + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, + &Buff->CursorInfo, sizeof(Buff->CursorInfo), NULL, 0, + &BytesReturned, NULL)) { - DPRINT1( "Failed to set cursor info\n" ); - return FALSE; + DPRINT1( "Failed to set cursor info\n" ); + return FALSE; } - return TRUE; + return TRUE; } static BOOL WINAPI TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) { - CONSOLE_SCREEN_BUFFER_INFO Info; - DWORD BytesReturned; + CONSOLE_SCREEN_BUFFER_INFO Info; + DWORD BytesReturned; - if (ActiveConsole->ActiveBuffer != Buff) + if (ActiveConsole->ActiveBuffer != Buff) { - return TRUE; + return TRUE; } - Info.dwCursorPosition.X = Buff->CurrentX; - Info.dwCursorPosition.Y = Buff->CurrentY; - Info.wAttributes = Buff->DefaultAttrib; + Info.dwCursorPosition.X = Buff->CurrentX; + Info.dwCursorPosition.Y = Buff->CurrentY; + Info.wAttributes = Buff->DefaultAttrib; - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, - &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, - &BytesReturned, NULL)) + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, + &Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0, + &BytesReturned, NULL)) { - DPRINT1( "Failed to set cursor position\n" ); - return FALSE; + DPRINT1( "Failed to set cursor position\n" ); + return FALSE; } - return TRUE; + return TRUE; } static BOOL WINAPI @@ -261,32 +261,32 @@ TuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) static BOOL WINAPI TuiChangeTitle(PCSRSS_CONSOLE Console) { - return TRUE; + return TRUE; } static VOID WINAPI TuiCleanupConsole(PCSRSS_CONSOLE Console) { - DestroyWindow(Console->hWindow); + DestroyWindow(Console->hWindow); - EnterCriticalSection(&ActiveConsoleLock); + EnterCriticalSection(&ActiveConsoleLock); - /* Switch to next console */ - if (ActiveConsole == Console) + /* Switch to next console */ + if (ActiveConsole == Console) { - ActiveConsole = Console->Next != Console ? Console->Next : NULL; + ActiveConsole = Console->Next != Console ? Console->Next : NULL; } - if (Console->Next != Console) + if (Console->Next != Console) { - Console->Prev->Next = Console->Next; - Console->Next->Prev = Console->Prev; + Console->Prev->Next = Console->Next; + Console->Next->Prev = Console->Prev; } - LeaveCriticalSection(&ActiveConsoleLock); + LeaveCriticalSection(&ActiveConsoleLock); - if (NULL != ActiveConsole) + if (NULL != ActiveConsole) { - ConioDrawConsole(ActiveConsole); + ConioDrawConsole(ActiveConsole); } } @@ -306,179 +306,179 @@ TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD DWORD WINAPI TuiConsoleThread (PVOID Data) { - PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data; - HWND NewWindow; - MSG msg; + PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data; + HWND NewWindow; + MSG msg; - NewWindow = CreateWindowW(L"TuiConsoleWindowClass", - Console->Title.Buffer, - 0, - -32000, -32000, 0, 0, - NULL, NULL, - (HINSTANCE) GetModuleHandleW(NULL), - (PVOID) Console); - Console->hWindow = NewWindow; - if (NULL == NewWindow) + NewWindow = CreateWindowW(L"TuiConsoleWindowClass", + Console->Title.Buffer, + 0, + -32000, -32000, 0, 0, + NULL, NULL, + (HINSTANCE) GetModuleHandleW(NULL), + (PVOID) Console); + Console->hWindow = NewWindow; + if (NULL == NewWindow) { - DPRINT1("CSR: Unable to create console window\n"); - return 1; + DPRINT1("CSR: Unable to create console window\n"); + return 1; } - SetForegroundWindow(Console->hWindow); + SetForegroundWindow(Console->hWindow); - while (TRUE) + while (TRUE) { - GetMessageW(&msg, 0, 0, 0); - DispatchMessage(&msg); - TranslateMessage(&msg); + GetMessageW(&msg, 0, 0, 0); + DispatchMessage(&msg); + TranslateMessage(&msg); - if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR || - msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || - msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) + if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR || + msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || + msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) { - ConioProcessKey(&msg, Console, TRUE); + ConioProcessKey(&msg, Console, TRUE); } } - return 0; + return 0; } static CSRSS_CONSOLE_VTBL TuiVtbl = { - TuiInitScreenBuffer, - TuiWriteStream, - TuiDrawRegion, - TuiSetCursorInfo, - TuiSetScreenInfo, - TuiUpdateScreenInfo, - TuiChangeTitle, - TuiCleanupConsole, - TuiChangeIcon, - TuiResizeBuffer, + TuiInitScreenBuffer, + TuiWriteStream, + TuiDrawRegion, + TuiSetCursorInfo, + TuiSetScreenInfo, + TuiUpdateScreenInfo, + TuiChangeTitle, + TuiCleanupConsole, + TuiChangeIcon, + TuiResizeBuffer, }; NTSTATUS FASTCALL TuiInitConsole(PCSRSS_CONSOLE Console) { - HANDLE ThreadHandle; + HANDLE ThreadHandle; - if (! ConsInitialized) + if (! ConsInitialized) { - ConsInitialized = TRUE; - if (! TuiInit(Console->CodePage)) + ConsInitialized = TRUE; + if (! TuiInit(Console->CodePage)) { - ConsInitialized = FALSE; - return STATUS_UNSUCCESSFUL; + ConsInitialized = FALSE; + return STATUS_UNSUCCESSFUL; } } - Console->Vtbl = &TuiVtbl; - Console->hWindow = NULL; - Console->Size = PhysicalConsoleSize; - Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X; - Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y; + Console->Vtbl = &TuiVtbl; + Console->hWindow = NULL; + Console->Size = PhysicalConsoleSize; + Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X; + Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y; - ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread, - Console, 0, NULL); - if (NULL == ThreadHandle) + ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread, + Console, 0, NULL); + if (NULL == ThreadHandle) { - DPRINT1("CSR: Unable to create console thread\n"); - return STATUS_UNSUCCESSFUL; + DPRINT1("CSR: Unable to create console thread\n"); + return STATUS_UNSUCCESSFUL; } - CloseHandle(ThreadHandle); + CloseHandle(ThreadHandle); - EnterCriticalSection(&ActiveConsoleLock); - if (NULL != ActiveConsole) + EnterCriticalSection(&ActiveConsoleLock); + if (NULL != ActiveConsole) { - Console->Prev = ActiveConsole; - Console->Next = ActiveConsole->Next; - ActiveConsole->Next->Prev = Console; - ActiveConsole->Next = Console; + Console->Prev = ActiveConsole; + Console->Next = ActiveConsole->Next; + ActiveConsole->Next->Prev = Console; + ActiveConsole->Next = Console; } - else + else { - Console->Prev = Console; - Console->Next = Console; + Console->Prev = Console; + Console->Next = Console; } - ActiveConsole = Console; - LeaveCriticalSection(&ActiveConsoleLock); + ActiveConsole = Console; + LeaveCriticalSection(&ActiveConsoleLock); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } PCSRSS_CONSOLE FASTCALL TuiGetFocusConsole(VOID) { - return ActiveConsole; + return ActiveConsole; } BOOL FASTCALL TuiSwapConsole(int Next) { - static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */ - DWORD BytesReturned; - ANSI_STRING Title; - void * Buffer; - COORD *pos; + static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */ + DWORD BytesReturned; + ANSI_STRING Title; + void * Buffer; + COORD *pos; - if (0 != Next) + if (0 != Next) { - /* alt-tab, swap consoles */ - /* move SwapConsole to next console, and print its title */ - EnterCriticalSection(&ActiveConsoleLock); - if (! SwapConsole) + /* alt-tab, swap consoles */ + /* move SwapConsole to next console, and print its title */ + EnterCriticalSection(&ActiveConsoleLock); + if (! SwapConsole) { - SwapConsole = ActiveConsole; + SwapConsole = ActiveConsole; } - SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev); - Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title); - Title.Length = 0; - Buffer = HeapAlloc(Win32CsrApiHeap, - 0, - sizeof(COORD) + Title.MaximumLength); - pos = (COORD *)Buffer; - Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD )); + SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev); + Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title); + Title.Length = 0; + Buffer = HeapAlloc(Win32CsrApiHeap, + 0, + sizeof(COORD) + Title.MaximumLength); + pos = (COORD *)Buffer; + Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD )); - RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE); - pos->Y = PhysicalConsoleSize.Y / 2; - pos->X = (PhysicalConsoleSize.X - Title.Length) / 2; - /* redraw the console to clear off old title */ - ConioDrawConsole(ActiveConsole); - if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, - NULL, 0, Buffer, sizeof(COORD) + Title.Length, - &BytesReturned, NULL)) + RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE); + pos->Y = PhysicalConsoleSize.Y / 2; + pos->X = (PhysicalConsoleSize.X - Title.Length) / 2; + /* redraw the console to clear off old title */ + ConioDrawConsole(ActiveConsole); + if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, + NULL, 0, Buffer, sizeof(COORD) + Title.Length, + &BytesReturned, NULL)) { - DPRINT1( "Error writing to console\n" ); + DPRINT1( "Error writing to console\n" ); } - HeapFree(Win32CsrApiHeap, 0, Buffer); - LeaveCriticalSection(&ActiveConsoleLock); + HeapFree(Win32CsrApiHeap, 0, Buffer); + LeaveCriticalSection(&ActiveConsoleLock); - return TRUE; + return TRUE; } - else if (NULL != SwapConsole) + else if (NULL != SwapConsole) { - EnterCriticalSection(&ActiveConsoleLock); - if (SwapConsole != ActiveConsole) + EnterCriticalSection(&ActiveConsoleLock); + if (SwapConsole != ActiveConsole) { - /* first remove swapconsole from the list */ - SwapConsole->Prev->Next = SwapConsole->Next; - SwapConsole->Next->Prev = SwapConsole->Prev; - /* now insert before activeconsole */ - SwapConsole->Next = ActiveConsole; - SwapConsole->Prev = ActiveConsole->Prev; - ActiveConsole->Prev->Next = SwapConsole; - ActiveConsole->Prev = SwapConsole; + /* first remove swapconsole from the list */ + SwapConsole->Prev->Next = SwapConsole->Next; + SwapConsole->Next->Prev = SwapConsole->Prev; + /* now insert before activeconsole */ + SwapConsole->Next = ActiveConsole; + SwapConsole->Prev = ActiveConsole->Prev; + ActiveConsole->Prev->Next = SwapConsole; + ActiveConsole->Prev = SwapConsole; } - ActiveConsole = SwapConsole; - SwapConsole = NULL; - ConioDrawConsole(ActiveConsole); - LeaveCriticalSection(&ActiveConsoleLock); - return TRUE; + ActiveConsole = SwapConsole; + SwapConsole = NULL; + ConioDrawConsole(ActiveConsole); + LeaveCriticalSection(&ActiveConsoleLock); + return TRUE; } - else + else { - return FALSE; + return FALSE; } } diff --git a/subsystems/win32/csrss/win32csr/win32csr.h b/subsystems/win32/csrss/win32csr/win32csr.h new file mode 100644 index 00000000000..0417740984e --- /dev/null +++ b/subsystems/win32/csrss/win32csr/win32csr.h @@ -0,0 +1,79 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: subsys/csrss/win32csr/win32csr.h + * PURPOSE: Interface to win32csr.dll + */ + +#pragma once + +#include +#include + +extern HANDLE Win32CsrApiHeap; +extern HINSTANCE Win32CsrDllHandle; + +typedef struct Object_tt +{ + LONG Type; + struct tagCSRSS_CONSOLE *Console; + LONG AccessRead, AccessWrite; + LONG ExclusiveRead, ExclusiveWrite; + LONG HandleCount; +} Object_t; + +typedef struct _CSRSS_HANDLE +{ + Object_t *Object; + DWORD Access; + BOOL Inheritable; + DWORD ShareMode; +} CSRSS_HANDLE, *PCSRSS_HANDLE; + +typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); + +typedef struct tagCSRSS_OBJECT_DEFINITION +{ + LONG Type; + CSR_CLEANUP_OBJECT_PROC CsrCleanupObjectProc; +} CSRSS_OBJECT_DEFINITION, *PCSRSS_OBJECT_DEFINITION; + +/* handle.c */ +NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, + PHANDLE Handle, + Object_t *Object, + DWORD Access, + BOOL Inheritable, + DWORD ShareMode); +NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, + HANDLE Handle, + Object_t **Object, + DWORD Access, + long Type); +VOID FASTCALL Win32CsrUnlockObject(Object_t *Object); +NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, + HANDLE Object); +NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); +NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, + PCSRSS_PROCESS_DATA TargetProcessData); +CSR_API(CsrGetHandle); +CSR_API(CsrCloseHandle); +CSR_API(CsrVerifyHandle); +CSR_API(CsrDuplicateHandle); +CSR_API(CsrGetInputWaitHandle); + +BOOL FASTCALL Win32CsrValidateBuffer(PCSRSS_PROCESS_DATA ProcessData, + PVOID Buffer, + SIZE_T NumElements, + SIZE_T ElementSize); +NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, + PVOID Context); + +/* exitros.c */ +CSR_API(CsrExitReactos); +CSR_API(CsrSetLogonNotifyWindow); +CSR_API(CsrRegisterLogonProcess); + + +/* EOF */ diff --git a/subsystems/win32/csrss/win32csr/win32csr.rbuild b/subsystems/win32/csrss/win32csr/win32csr.rbuild index eec81fcba60..c6d4843abea 100644 --- a/subsystems/win32/csrss/win32csr/win32csr.rbuild +++ b/subsystems/win32/csrss/win32csr/win32csr.rbuild @@ -17,12 +17,16 @@ pseh w32csr.h alias.c - conio.c + coninput.c + conoutput.c + console.c desktopbg.c dllmain.c exitros.c guiconsole.c + handle.c harderror.c + lineinput.c tuiconsole.c appswitch.c win32csr.rc diff --git a/subsystems/win32/csrss/win32csr/win32csr.spec b/subsystems/win32/csrss/win32csr/win32csr.spec index 85e81a759b4..2e513757b03 100644 --- a/subsystems/win32/csrss/win32csr/win32csr.spec +++ b/subsystems/win32/csrss/win32csr/win32csr.spec @@ -1 +1 @@ -@ stdcall Win32CsrInitialization(ptr ptr ptr ptr ptr ptr) +@ stdcall Win32CsrInitialization(ptr ptr ptr ptr) diff --git a/subsystems/win32/win32k/include/class.h b/subsystems/win32/win32k/include/class.h index ac36f6b32ce..27b3baf1f83 100644 --- a/subsystems/win32/win32k/include/class.h +++ b/subsystems/win32/win32k/include/class.h @@ -65,11 +65,6 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName, IN HINSTANCE hInstance, OUT PCLSMENUNAME pClassMenuName); -ULONG_PTR -UserGetClassLongPtr(IN PCLS Class, - IN INT Index, - IN BOOL Ansi); - RTL_ATOM IntGetClassAtom(IN PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, @@ -77,6 +72,9 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL); +PCLS +IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance); + PCLS FASTCALL IntCreateClass(IN CONST WNDCLASSEXW* lpwcx, diff --git a/subsystems/win32/win32k/include/cursoricon.h b/subsystems/win32/win32k/include/cursoricon.h index 280ab555601..851428c6c68 100644 --- a/subsystems/win32/win32k/include/cursoricon.h +++ b/subsystems/win32/win32k/include/cursoricon.h @@ -69,20 +69,19 @@ typedef struct _SYSTEM_CURSORINFO BOOL ScreenSaverRunning; } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO; -BOOL FASTCALL InitCursorImpl(); -PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(); +BOOL InitCursorImpl(); +PCURICON_OBJECT IntCreateCurIconHandle(); VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process); BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); -BOOL UserSetCursorPos( INT x, INT y); +BOOL UserSetCursorPos( INT x, INT y, BOOL CallHooks); int UserShowCursor(BOOL bShow); -PSYSTEM_CURSORINFO FASTCALL -IntGetSysCursorInfo(); +PSYSTEM_CURSORINFO IntGetSysCursorInfo(); #define IntReleaseCurIconObject(CurIconObj) \ UserDereferenceObject(CurIconObj) diff --git a/subsystems/win32/win32k/include/intgdi.h b/subsystems/win32/win32k/include/intgdi.h index 1b7a700c32f..d547ba460d6 100644 --- a/subsystems/win32/win32k/include/intgdi.h +++ b/subsystems/win32/win32k/include/intgdi.h @@ -122,10 +122,15 @@ IntGdiPolyPolygon(DC *dc, PULONG PolyCounts, int Count); -BOOL FASTCALL IntGdiGradientFill(DC *dc, +BOOL +NTAPI +GreGradientFill( + HDC hdc, PTRIVERTEX pVertex, - ULONG uVertex, - PVOID pMesh, ULONG uMesh, ULONG ulMode); + ULONG nVertex, + PVOID pMesh, + ULONG nMesh, + ULONG ulMode); /* DC functions */ diff --git a/subsystems/win32/win32k/include/palette.h b/subsystems/win32/win32k/include/palette.h index 43f59e6efca..76839b075f5 100644 --- a/subsystems/win32/win32k/include/palette.h +++ b/subsystems/win32/win32k/include/palette.h @@ -2,8 +2,6 @@ #include -#define NO_MAPPING - #define PALETTE_FIXED 0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */ #define PALETTE_VIRTUAL 0x0002 /* no mapping needed - pixel == pixel color */ @@ -79,9 +77,6 @@ BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody); HPALETTE FASTCALL PALETTE_Init (VOID); VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); -#ifndef NO_MAPPING -INT APIENTRY PALETTE_SetMapping(PALOBJ* palPtr, UINT uStart, UINT uNum, BOOL mapOnly); -#endif INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); INT FASTCALL PALETTE_GetObject(PPALETTE pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer); diff --git a/subsystems/win32/win32k/include/timer.h b/subsystems/win32/win32k/include/timer.h index a41b8c30dbe..9b2b07f8c9d 100644 --- a/subsystems/win32/win32k/include/timer.h +++ b/subsystems/win32/win32k/include/timer.h @@ -23,12 +23,12 @@ typedef struct _TIMER #define TMRF_ONESHOT 0x0010 #define TMRF_WAITING 0x0020 #define TMRF_TIFROMWND 0x0040 -#define TMRF_DELETEPENDING 0x8000 extern PKTIMER MasterTimer; NTSTATUS FASTCALL InitTimerImpl(VOID); BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti); +BOOL FASTCALL DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window); BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer); UINT_PTR FASTCALL IntSetTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type); PTIMER FASTCALL FindSystemTimer(PMSG); diff --git a/subsystems/win32/win32k/include/userfuncs.h b/subsystems/win32/win32k/include/userfuncs.h index 7ad47e625bc..d31e66faea9 100644 --- a/subsystems/win32/win32k/include/userfuncs.h +++ b/subsystems/win32/win32k/include/userfuncs.h @@ -122,15 +122,11 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread); HWND FASTCALL UserGetShellWindow(VOID); -HWND FASTCALL UserGetWindow(HWND hWnd, UINT Relationship); - HDC FASTCALL UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags); BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Wnd); -LONG FASTCALL UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi); - PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type); /*************** MENU.C ***************/ diff --git a/subsystems/win32/win32k/include/window.h b/subsystems/win32/win32k/include/window.h index 90143244458..79a8df2d003 100644 --- a/subsystems/win32/win32k/include/window.h +++ b/subsystems/win32/win32k/include/window.h @@ -37,11 +37,8 @@ typedef struct _WINDOW_OBJECT struct _WINDOW_OBJECT* spwndChild; struct _WINDOW_OBJECT* spwndNext; struct _WINDOW_OBJECT* spwndPrev; - /* Handle to the parent window. */ struct _WINDOW_OBJECT* spwndParent; - /* Handle to the owner window. */ - HWND hOwner; // Use spwndOwner - + struct _WINDOW_OBJECT* spwndOwner; /* Scrollbar info */ PSBINFOEX pSBInfo; // convert to PSBINFO @@ -125,10 +122,6 @@ IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type); PWINDOW_OBJECT FASTCALL IntGetParent(PWINDOW_OBJECT Wnd); -PWINDOW_OBJECT FASTCALL -IntGetOwner(PWINDOW_OBJECT Wnd); - - INT FASTCALL IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn); @@ -141,9 +134,6 @@ IntGetWindowInfo(PWINDOW_OBJECT WindowObject, PWINDOWINFO pwi); VOID FASTCALL IntGetWindowBorderMeasures(PWINDOW_OBJECT WindowObject, UINT *cx, UINT *cy); -BOOL FASTCALL -IntAnyPopup(VOID); - BOOL FASTCALL IntIsWindowInDestroy(PWINDOW_OBJECT Window); @@ -155,7 +145,7 @@ IntDefWindowProc( PWINDOW_OBJECT Window, UINT Msg, WPARAM wParam, LPARAM lParam, VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG); -PWND APIENTRY co_IntCreateWindowEx(DWORD,PUNICODE_STRING,PLARGE_STRING,DWORD,LONG,LONG,LONG,LONG,HWND,HMENU,HINSTANCE,LPVOID,DWORD,BOOL); +PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING); WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL); /* EOF */ diff --git a/subsystems/win32/win32k/include/winpos.h b/subsystems/win32/win32k/include/winpos.h index 9bb6cfffaba..7d14676e630 100644 --- a/subsystems/win32/win32k/include/winpos.h +++ b/subsystems/win32/win32k/include/winpos.h @@ -25,6 +25,8 @@ co_WinPosSetWindowPos(PWINDOW_OBJECT Wnd, HWND WndInsertAfter, INT x, INT y, INT INT cy, UINT flags); BOOLEAN FASTCALL co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd); +void FASTCALL +co_WinPosSendSizeMove(PWINDOW_OBJECT Window); USHORT FASTCALL co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint, PWINDOW_OBJECT* Window); diff --git a/subsystems/win32/win32k/main/dllmain.c b/subsystems/win32/win32k/main/dllmain.c index 3eb5753d231..88684b6cf80 100644 --- a/subsystems/win32/win32k/main/dllmain.c +++ b/subsystems/win32/win32k/main/dllmain.c @@ -292,6 +292,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread, HOOK_DestroyThreadHooks(Thread); /* Cleanup timers */ DestroyTimersForThread(Win32Thread); + KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); UnregisterThreadHotKeys(Thread); /* what if this co_ func crash in umode? what will clean us up then? */ co_DestroyThreadWindows(Thread); diff --git a/subsystems/win32/win32k/misc/driver.c b/subsystems/win32/win32k/misc/driver.c index 1219f94effa..8b25b137b33 100644 --- a/subsystems/win32/win32k/misc/driver.c +++ b/subsystems/win32/win32k/misc/driver.c @@ -167,7 +167,7 @@ PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name) if (!NT_SUCCESS(Status)) { - ExFreePool(FullName); + ExFreePoolWithTag(FullName, TAG_DRIVER); return NULL; } @@ -572,8 +572,8 @@ BOOL DRIVER_UnregisterDriver(LPCWSTR Name) if (Driver != NULL) { - ExFreePool(Driver->Name); - ExFreePool(Driver); + ExFreePoolWithTag(Driver->Name, TAG_DRIVER); + ExFreePoolWithTag(Driver, TAG_DRIVER); return TRUE; } @@ -597,7 +597,7 @@ INT DRIVER_ReferenceDriver (LPCWSTR Name) Driver = Driver->Next; } DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); - assert( GenericDriver != 0 ); + ASSERT( GenericDriver != 0 ); return ++GenericDriver->ReferenceCount; } @@ -615,7 +615,7 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name) Driver = Driver->Next; } DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); - assert( GenericDriver != 0 ); + ASSERT( GenericDriver != 0 ); return --GenericDriver->ReferenceCount; } /* EOF */ diff --git a/subsystems/win32/win32k/ntuser/accelerator.c b/subsystems/win32/win32k/ntuser/accelerator.c index b59f1d1b7de..d963344af32 100644 --- a/subsystems/win32/win32k/ntuser/accelerator.c +++ b/subsystems/win32/win32k/ntuser/accelerator.c @@ -436,7 +436,7 @@ NtUserDestroyAcceleratorTable( if (Accel->Table != NULL) { - ExFreePool(Accel->Table); + ExFreePoolWithTag(Accel->Table, TAG_ACCEL); Accel->Table = NULL; } diff --git a/subsystems/win32/win32k/ntuser/callproc.c b/subsystems/win32/win32k/ntuser/callproc.c index dc8496dd431..f2298256d08 100644 --- a/subsystems/win32/win32k/ntuser/callproc.c +++ b/subsystems/win32/win32k/ntuser/callproc.c @@ -185,9 +185,7 @@ UserGetCPD( Example: If pWnd is created from Ansi and lpfnXxyz is assumed to be Ansi, caller will ask for Unicode Proc return Proc or CallProcData handle. - - This function should replaced NtUserGetClassLong and NtUserGetWindowLong. - */ +*/ ULONG_PTR APIENTRY NtUserGetCPD( diff --git a/subsystems/win32/win32k/ntuser/class.c b/subsystems/win32/win32k/ntuser/class.c index b24b26f4199..814aadb67dc 100644 --- a/subsystems/win32/win32k/ntuser/class.c +++ b/subsystems/win32/win32k/ntuser/class.c @@ -1207,6 +1207,57 @@ FoundClass: return Atom; } +PCLS +IntGetAndReferenceClass(PUNICODE_STRING ClassName, HINSTANCE hInstance) +{ + PCLS *ClassLink, Class = NULL; + RTL_ATOM ClassAtom; + PTHREADINFO pti; + + pti = PsGetCurrentThreadWin32Thread(); + + if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED )) + { + UserRegisterSystemClasses(); + } + + /* Check the class. */ + + DPRINT("Class %wZ\n", ClassName); + + ClassAtom = IntGetClassAtom(ClassName, + hInstance, + pti->ppi, + &Class, + &ClassLink); + + if (ClassAtom == (RTL_ATOM)0) + { + if (IS_ATOM(ClassName->Buffer)) + { + DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer); + } + else + { + DPRINT1("Class \"%wZ\" not found\n", ClassName); + } + + SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS); + return NULL; + } + DPRINT("ClassAtom %x\n", ClassAtom); + Class = IntReferenceClass(Class, + ClassLink, + pti->rpdesk); + if (Class == NULL) + { + DPRINT1("Failed to reference window class!\n"); + return NULL; + } + + return Class; +} + RTL_ATOM UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx, IN PUNICODE_STRING ClassName, @@ -1464,96 +1515,6 @@ UserGetClassName(IN PCLS Class, return Ret; } -ULONG_PTR -UserGetClassLongPtr(IN PCLS Class, - IN INT Index, - IN BOOL Ansi) -{ - ULONG_PTR Ret = 0; - - if (Index >= 0) - { - PULONG_PTR Data; - - TRACE("GetClassLong(%d)\n", Index); - if (Index + sizeof(ULONG_PTR) < Index || - Index + sizeof(ULONG_PTR) > Class->cbclsExtra) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - - Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index); - - /* FIXME - Data might be a unaligned pointer! Might be a problem on - certain architectures, maybe using RtlCopyMemory is a - better choice for those architectures! */ - - TRACE("Result: %x\n", Ret); - return *Data; - } - - switch (Index) - { - case GCL_CBWNDEXTRA: - Ret = (ULONG_PTR)Class->cbwndExtra; - break; - - case GCL_CBCLSEXTRA: - Ret = (ULONG_PTR)Class->cbclsExtra; - break; - - case GCLP_HBRBACKGROUND: - Ret = (ULONG_PTR)Class->hbrBackground; - break; - - case GCLP_HCURSOR: - /* FIXME - get handle from pointer to CURSOR object */ - Ret = (ULONG_PTR)Class->hCursor; - break; - - case GCLP_HICON: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIcon; - break; - - case GCLP_HICONSM: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIconSm; - break; - - case GCLP_HMODULE: - Ret = (ULONG_PTR)Class->hModule; - break; - - case GCLP_MENUNAME: - /* NOTE: Returns pointer in kernel heap! */ - if (Ansi) - Ret = (ULONG_PTR)Class->lpszClientAnsiMenuName; - else - Ret = (ULONG_PTR)Class->lpszClientUnicodeMenuName; - break; - - case GCL_STYLE: - Ret = (ULONG_PTR)Class->style; - break; - - case GCLP_WNDPROC: - Ret = (ULONG_PTR)IntGetClassWndProc(Class, Ansi); - break; - - case GCW_ATOM: - Ret = (ULONG_PTR)Class->atomClassName; - break; - - default: - SetLastWin32Error(ERROR_INVALID_INDEX); - break; - } - - return Ret; -} - static BOOL IntSetClassMenuName(IN PCLS Class, IN PUNICODE_STRING MenuName) @@ -2139,45 +2100,6 @@ InvalidParameter: return Ret; } -ULONG_PTR APIENTRY -NtUserGetClassLong(IN HWND hWnd, - IN INT Offset, - IN BOOL Ansi) -{ - PWINDOW_OBJECT Window; - ULONG_PTR Ret = 0; - - if (Offset != GCLP_WNDPROC) - { - UserEnterShared(); - } - else - { - UserEnterExclusive(); - } - - Window = UserGetWindowObject(hWnd); - if (Window != NULL) - { - Ret = UserGetClassLongPtr(Window->Wnd->pcls, - Offset, - Ansi); - - if ( Ret != 0 && - Offset == GCLP_MENUNAME && - Window->Wnd->pcls->MenuNameIsString) - { - Ret = (ULONG_PTR)UserHeapAddressToUser((PVOID)Ret); - } - } - - UserLeave(); - - return Ret; -} - - - ULONG_PTR APIENTRY NtUserSetClassLong(HWND hWnd, INT Offset, diff --git a/subsystems/win32/win32k/ntuser/cursoricon.c b/subsystems/win32/win32k/ntuser/cursoricon.c index 3fe0211ea53..832d820a98e 100644 --- a/subsystems/win32/win32k/ntuser/cursoricon.c +++ b/subsystems/win32/win32k/ntuser/cursoricon.c @@ -46,7 +46,7 @@ static LIST_ENTRY gCurIconList; SYSTEM_CURSORINFO gSysCursorInfo; -BOOL FASTCALL +BOOL InitCursorImpl() { ExInitializePagedLookasideList(&gProcessLookasideList, @@ -70,7 +70,7 @@ InitCursorImpl() return TRUE; } -PSYSTEM_CURSORINFO FASTCALL +PSYSTEM_CURSORINFO IntGetSysCursorInfo() { return &gSysCursorInfo; @@ -175,10 +175,12 @@ UserSetCursor( return hOldCursor; } -BOOL UserSetCursorPos( INT x, INT y) +BOOL UserSetCursorPos( INT x, INT y, BOOL CallHooks) { PWINDOW_OBJECT DesktopWindow; PSYSTEM_CURSORINFO CurInfo; + LARGE_INTEGER LargeTickCount; + MSLLHOOKSTRUCT MouseHookData; HDC hDC; MSG Msg; @@ -221,6 +223,9 @@ BOOL UserSetCursorPos( INT x, INT y) gpsi->ptCursor.x = x; gpsi->ptCursor.y = y; + KeQueryTickCount(&LargeTickCount); + Msg.time = MsqCalculateMessageTime(&LargeTickCount); + //Move the mouse pointer GreMovePointer(hDC, x, y); @@ -229,8 +234,39 @@ BOOL UserSetCursorPos( INT x, INT y) Msg.wParam = CurInfo->ButtonsDown; Msg.lParam = MAKELPARAM(x, y); Msg.pt = gpsi->ptCursor; - MsqInsertSystemMessage(&Msg); + MouseHookData.pt.x = LOWORD(Msg.lParam); + MouseHookData.pt.y = HIWORD(Msg.lParam); + switch(Msg.message) + { + case WM_MOUSEWHEEL: + MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg.wParam)); + break; + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_XBUTTONDBLCLK: + case WM_NCXBUTTONDOWN: + case WM_NCXBUTTONUP: + case WM_NCXBUTTONDBLCLK: + MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg.wParam)); + break; + default: + MouseHookData.mouseData = 0; + break; + } + + MouseHookData.flags = 0; + MouseHookData.time = Msg.time; + MouseHookData.dwExtraInfo = 0; + + if (CallHooks) + { + /* If the hook procedure returned non zero, dont send the message */ + if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg.message, (LPARAM) &MouseHookData)) + return FALSE; + } + + MsqInsertSystemMessage(&Msg); return TRUE; } @@ -342,7 +378,7 @@ IntFindExistingCurIconObject(HMODULE hModule, return NULL; } -PCURICON_OBJECT FASTCALL +PCURICON_OBJECT IntCreateCurIconHandle() { PCURICON_OBJECT CurIcon; @@ -814,7 +850,7 @@ NtUserClipCursor( CurInfo->CursorClipInfo.Right = min(Rect.right, DesktopWindow->Wnd->rcWindow.right); CurInfo->CursorClipInfo.Bottom = min(Rect.bottom, DesktopWindow->Wnd->rcWindow.bottom); - UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y); + UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE); RETURN(TRUE); } diff --git a/subsystems/win32/win32k/ntuser/defwnd.c b/subsystems/win32/win32k/ntuser/defwnd.c index f5e2bd1fc1d..afc60e852ae 100644 --- a/subsystems/win32/win32k/ntuser/defwnd.c +++ b/subsystems/win32/win32k/ntuser/defwnd.c @@ -67,7 +67,7 @@ IntClientShutdown( co_IntSendMessage(WndChild->hSelf, WM_ENDSESSION, KillTimers, lParams); if (KillTimers) { - MsqRemoveTimersWindow(WndChild->pti->MessageQueue, WndChild->hSelf); + DestroyTimersForWindow(WndChild->pti, WndChild); } lResult = MCSR_SHUTDOWNFINISHED; } @@ -90,7 +90,7 @@ IntClientShutdown( co_IntSendMessage(pWindow->hSelf, WM_ENDSESSION, KillTimers, lParams); if (KillTimers) { - MsqRemoveTimersWindow(pWindow->pti->MessageQueue, pWindow->hSelf); + DestroyTimersForWindow(pWindow->pti, pWindow); } lResult = MCSR_SHUTDOWNFINISHED; } @@ -129,7 +129,7 @@ IntDefWindowProc( { if ((Wnd->style & WS_VISIBLE) && wParam) break; if (!(Wnd->style & WS_VISIBLE) && !wParam) break; - if (!Window->hOwner) break; + if (!Window->spwndOwner) break; if (LOWORD(lParam)) { if (wParam) diff --git a/subsystems/win32/win32k/ntuser/desktop.c b/subsystems/win32/win32k/ntuser/desktop.c index 1c972f95075..57a5be135e7 100644 --- a/subsystems/win32/win32k/ntuser/desktop.c +++ b/subsystems/win32/win32k/ntuser/desktop.c @@ -885,6 +885,7 @@ NtUserCreateDesktop( UNICODE_STRING ClassName, MenuName; LARGE_STRING WindowName; PWND pWnd = NULL; + CREATESTRUCTW Cs; DECLARE_RETURN(HDESK); DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); @@ -1079,20 +1080,14 @@ NtUserCreateDesktop( RtlZeroMemory(&MenuName, sizeof(MenuName)); RtlZeroMemory(&WindowName, sizeof(WindowName)); - pWnd = co_IntCreateWindowEx( 0, - &ClassName, - &WindowName, - (WS_POPUP|WS_CLIPCHILDREN), - 0, - 0, - 100, - 100, - NULL, - NULL, - hModClient, - NULL, - 0, - TRUE); + RtlZeroMemory(&Cs, sizeof(Cs)); + Cs.cx = Cs.cy = 100; + Cs.style = WS_POPUP|WS_CLIPCHILDREN; + Cs.hInstance = hModClient; + Cs.lpszName = (LPCWSTR) &WindowName; + Cs.lpszClass = (LPCWSTR) &ClassName; + + pWnd = co_UserCreateWindowEx(&Cs, &ClassName, &WindowName); if (!pWnd) { DPRINT1("Failed to create Message window handle\n"); @@ -1428,7 +1423,7 @@ NtUserPaintDesktop(HDC hDC) RETURN(FALSE); } - DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->pcls, GCL_HBRBACKGROUND, FALSE); + DesktopBrush = (HBRUSH)WndDesktop->Wnd->pcls->hbrBackground; /* diff --git a/subsystems/win32/win32k/ntuser/focus.c b/subsystems/win32/win32k/ntuser/focus.c index ee9c2ff93ad..59f364ed548 100644 --- a/subsystems/win32/win32k/ntuser/focus.c +++ b/subsystems/win32/win32k/ntuser/focus.c @@ -51,12 +51,14 @@ IntGetThreadFocusWindow(VOID) VOID FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd) { - if (hWndPrev) + PWINDOW_OBJECT WndPrev ; + + if (hWndPrev && (WndPrev = UserGetWindowObject(hWndPrev))) { co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0); co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE, - MAKEWPARAM(WA_INACTIVE, UserGetWindowLong(hWndPrev, GWL_STYLE, FALSE) & WS_MINIMIZE), - (LPARAM)hWnd); + MAKEWPARAM(WA_INACTIVE, WndPrev->Wnd->style & WS_MINIMIZE), + (LPARAM)hWnd); } } @@ -83,11 +85,11 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate) 0); } - if (UserGetWindow(hWnd, GW_HWNDPREV) != NULL) + if (Window->spwndPrev != NULL) co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd); } @@ -153,7 +155,7 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate) /* FIXME: WA_CLICKACTIVE */ co_IntSendMessageNoWait(hWnd, WM_ACTIVATE, MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, - UserGetWindowLong(hWnd, GWL_STYLE, FALSE) & WS_MINIMIZE), + Window->Wnd->style & WS_MINIMIZE), (LPARAM)hWndPrev); } } @@ -184,7 +186,7 @@ IntFindChildWindowToOwner(PWINDOW_OBJECT Root, PWINDOW_OBJECT Owner) for(Child = Root->spwndChild; Child; Child = Child->spwndNext) { - OwnerWnd = UserGetWindowObject(Child->hOwner); + OwnerWnd = Child->spwndOwner; if(!OwnerWnd) continue; diff --git a/subsystems/win32/win32k/ntuser/input.c b/subsystems/win32/win32k/ntuser/input.c index 006b0f123b0..8764e19d877 100644 --- a/subsystems/win32/win32k/ntuser/input.c +++ b/subsystems/win32/win32k/ntuser/input.c @@ -1128,7 +1128,7 @@ IntMouseInput(MOUSEINPUT *mi) if(mi->dwFlags & MOUSEEVENTF_MOVE) { - UserSetCursorPos(MousePos.x, MousePos.y); + UserSetCursorPos(MousePos.x, MousePos.y, TRUE); } if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN) { diff --git a/subsystems/win32/win32k/ntuser/kbdlayout.c b/subsystems/win32/win32k/ntuser/kbdlayout.c index 8ee11dc3983..5d04cd81902 100644 --- a/subsystems/win32/win32k/ntuser/kbdlayout.c +++ b/subsystems/win32/win32k/ntuser/kbdlayout.c @@ -199,7 +199,7 @@ static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId) ULONG hKl; LANGID langid; - NewKbl = ExAllocatePool(PagedPool, sizeof(KBL)); + NewKbl = ExAllocatePoolWithTag(PagedPool, sizeof(KBL), TAG_KEYBOARD); if(!NewKbl) { @@ -212,7 +212,7 @@ static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId) if(!UserLoadKbdDll(NewKbl->Name, &NewKbl->hModule, &NewKbl->KBTables)) { DPRINT("%s: failed to load %x dll!\n", __FUNCTION__, LocaleId); - ExFreePool(NewKbl); + ExFreePoolWithTag(NewKbl, TAG_KEYBOARD); return NULL; } @@ -401,7 +401,7 @@ BOOL UserUnloadKbl(PKBL pKbl) //Unload the layout EngUnloadImage(pKbl->hModule); RemoveEntryList(&pKbl->List); - ExFreePool(pKbl); + ExFreePoolWithTag(pKbl, TAG_KEYBOARD); } return TRUE; diff --git a/subsystems/win32/win32k/ntuser/message.c b/subsystems/win32/win32k/ntuser/message.c index b626b881db4..e78ce5aeca2 100644 --- a/subsystems/win32/win32k/ntuser/message.c +++ b/subsystems/win32/win32k/ntuser/message.c @@ -145,7 +145,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam) break; default: - assert(FALSE); + ASSERT(FALSE); Size = 0; break; } @@ -1625,12 +1625,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); - if (Window->pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { DPRINT1("Failed to unpack message parameters\n"); - RETURN(TRUE); } RETURN(TRUE); } @@ -2621,6 +2620,18 @@ NtUserMessageCall( } break; case FNID_SENDMESSAGECALLBACK: + { + PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo; + + if (!CallBackInfo) + break; + + if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam, + CallBackInfo->CallBack, CallBackInfo->Context, NULL)) + { + DPRINT1("Callback failure!\n"); + } + } break; // CallNextHook bypass. case FNID_CALLWNDPROC: diff --git a/subsystems/win32/win32k/ntuser/msgqueue.c b/subsystems/win32/win32k/ntuser/msgqueue.c index 5bfe414b5ed..33b8119a0d2 100644 --- a/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/subsystems/win32/win32k/ntuser/msgqueue.c @@ -171,38 +171,8 @@ MsqInitializeImpl(VOID) VOID FASTCALL MsqInsertSystemMessage(MSG* Msg) { - LARGE_INTEGER LargeTickCount; KIRQL OldIrql; ULONG Prev; - MSLLHOOKSTRUCT MouseHookData; - - KeQueryTickCount(&LargeTickCount); - Msg->time = MsqCalculateMessageTime(&LargeTickCount); - - MouseHookData.pt.x = LOWORD(Msg->lParam); - MouseHookData.pt.y = HIWORD(Msg->lParam); - switch(Msg->message) - { - case WM_MOUSEWHEEL: - MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam)); - break; - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - case WM_XBUTTONDBLCLK: - case WM_NCXBUTTONDOWN: - case WM_NCXBUTTONUP: - case WM_NCXBUTTONDBLCLK: - MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam)); - break; - default: - MouseHookData.mouseData = 0; - break; - } - MouseHookData.flags = 0; - MouseHookData.time = Msg->time; - MouseHookData.dwExtraInfo = 0; - if( co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData)) - return; /* * If we got WM_MOUSEMOVE and there are already messages in the @@ -924,7 +894,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) PLIST_ENTRY Entry; LRESULT Result; BOOL SenderReturned; - PUSER_SENT_MESSAGE_NOTIFY NotifyMessage; if (IsListEmpty(&MessageQueue->SentMessagesListHead)) { @@ -995,26 +964,16 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* Notify the sender if they specified a callback. */ + /* Call the callback if the message was sent with SendMessageCallback */ if (!SenderReturned && Message->CompletionCallback != NULL) { - if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool, - sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG))) - { - DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n"); - goto Notified; - } - NotifyMessage->CompletionCallback = - Message->CompletionCallback; - NotifyMessage->CompletionCallbackContext = - Message->CompletionCallbackContext; - NotifyMessage->Result = Result; - NotifyMessage->hWnd = Message->Msg.hwnd; - NotifyMessage->Msg = Message->Msg.message; - MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage); + co_IntCallSentMessageCallback(Message->CompletionCallback, + Message->Msg.hwnd, + Message->Msg.message, + Message->CompletionCallbackContext, + Result); } -Notified: /* Only if it is not a no wait message */ if (!(Message->HookMessage & MSQ_SENTNOWAIT)) @@ -1024,7 +983,7 @@ Notified: } /* free the message */ - ExFreePool(Message); + ExFreePoolWithTag(Message, TAG_USRMSG); return(TRUE); } @@ -1101,7 +1060,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) } /* free the message */ - ExFreePool(SentMessage); + ExFreePoolWithTag(SentMessage, TAG_USRMSG); CurrentEntry = MessageQueue->SentMessagesListHead.Flink; } @@ -1396,19 +1355,8 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil UINT MsgFilterMin, UINT MsgFilterMax) { PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent}; - LARGE_INTEGER TimerExpiry; - PLARGE_INTEGER Timeout; NTSTATUS ret; - if (MsqGetFirstTimerExpiry(MessageQueue, WndFilter, MsgFilterMin, MsgFilterMax, &TimerExpiry)) - { - Timeout = &TimerExpiry; - } - else - { - Timeout = NULL; - } - IdlePing(); // Going to wait so send Idle ping. UserLeaveCo(); @@ -1419,11 +1367,9 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil Executive, UserMode, FALSE, - Timeout, + NULL, NULL); - UserEnterCo(); - return ret; } diff --git a/subsystems/win32/win32k/ntuser/ntuser.c b/subsystems/win32/win32k/ntuser/ntuser.c index 569acfdc54c..b8f17849195 100644 --- a/subsystems/win32/win32k/ntuser/ntuser.c +++ b/subsystems/win32/win32k/ntuser/ntuser.c @@ -124,6 +124,8 @@ UserInitialize( NtUserUpdatePerUserSystemParameters(0, TRUE); + CsrInit(); + return STATUS_SUCCESS; } diff --git a/subsystems/win32/win32k/ntuser/painting.c b/subsystems/win32/win32k/ntuser/painting.c index 0e042410757..2564bac103f 100644 --- a/subsystems/win32/win32k/ntuser/painting.c +++ b/subsystems/win32/win32k/ntuser/painting.c @@ -1782,7 +1782,6 @@ BOOL UserDrawCaption( static GRADIENT_RECT gcap = {0, 1}; TRIVERTEX vert[2]; COLORREF Colors[2]; - PDC pMemDc; if (Wnd != NULL) { @@ -1835,20 +1834,12 @@ BOOL UserDrawCaption( vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00; vert[1].Alpha = 0; - pMemDc = DC_LockDc(hMemDc); - if(!pMemDc) - { - DPRINT1("%s: Can't lock dc!\n", __FUNCTION__); - goto cleanup; - } - - if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap, + if(!GreGradientFill(hMemDc, vert, 2, &gcap, 1, GRADIENT_FILL_RECT_H)) { DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__); } - DC_UnlockDc(pMemDc); } //if(uFlags & DC_GRADIENT) } diff --git a/subsystems/win32/win32k/ntuser/simplecall.c b/subsystems/win32/win32k/ntuser/simplecall.c index 77d8fb9d237..f46a75da2aa 100644 --- a/subsystems/win32/win32k/ntuser/simplecall.c +++ b/subsystems/win32/win32k/ntuser/simplecall.c @@ -110,14 +110,6 @@ NtUserCallNoParam(DWORD Routine) Result = (DWORD_PTR)MsqGetMessageExtraInfo(); break; - case NOPARAM_ROUTINE_ANYPOPUP: - Result = (DWORD_PTR)IntAnyPopup(); - break; - - case NOPARAM_ROUTINE_CSRSS_INITIALIZED: - Result = (DWORD_PTR)CsrInit(); - break; - case NOPARAM_ROUTINE_MSQCLEARWAKEMASK: RETURN( (DWORD_PTR)IntMsqClearWakeMask()); @@ -440,7 +432,7 @@ NtUserCallTwoParam( RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2)); case TWOPARAM_ROUTINE_SETCURSORPOS: - RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2)); + RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE)); } DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n", @@ -525,7 +517,7 @@ NtUserCallHwndLock( SWP_NOZORDER| SWP_NOACTIVATE| SWP_FRAMECHANGED ); - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd); } diff --git a/subsystems/win32/win32k/ntuser/timer.c b/subsystems/win32/win32k/ntuser/timer.c index 2d7b8d003d7..de8caeaafed 100644 --- a/subsystems/win32/win32k/ntuser/timer.c +++ b/subsystems/win32/win32k/ntuser/timer.c @@ -24,13 +24,14 @@ static LONG TimeLast = 0; #define MAX_ELAPSE_TIME 0x7FFFFFFF /* Windows 2000 has room for 32768 window-less timers */ -#define NUM_WINDOW_LESS_TIMERS 1024 +#define NUM_WINDOW_LESS_TIMERS 32768 static FAST_MUTEX Mutex; static RTL_BITMAP WindowLessTimersBitMap; static PVOID WindowLessTimersBitMapBuffer; static ULONG HintIndex = 0; +ERESOURCE TimerLock; #define IntLockWindowlessTimerBitmap() \ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Mutex) @@ -38,6 +39,19 @@ static ULONG HintIndex = 0; #define IntUnlockWindowlessTimerBitmap() \ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex) +#define TimerEnterExclusive() \ +{ \ + KeEnterCriticalRegion(); \ + ExAcquireResourceExclusiveLite(&TimerLock, TRUE); \ +} + +#define TimerLeave() \ +{ \ + ExReleaseResourceLite(&TimerLock); \ + KeLeaveCriticalRegion(); \ +} + + /* FUNCTIONS *****************************************************************/ static PTIMER @@ -49,14 +63,23 @@ CreateTimer(VOID) if (!FirstpTmr) { + ExInitializeResourceLite(&TimerLock); FirstpTmr = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER)); - if (FirstpTmr) InitializeListHead(&FirstpTmr->ptmrList); + if (FirstpTmr) + { + FirstpTmr->head.h = Handle; + InitializeListHead(&FirstpTmr->ptmrList); + } Ret = FirstpTmr; } else { Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER)); - if (Ret) InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList); + if (Ret) + { + Ret->head.h = Handle; + InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList); + } } return Ret; } @@ -66,13 +89,24 @@ BOOL FASTCALL RemoveTimer(PTIMER pTmr) { + BOOL Ret = FALSE; if (pTmr) { /* Set the flag, it will be removed when ready */ - pTmr->flags |= TMRF_DELETEPENDING; - return TRUE; + RemoveEntryList(&pTmr->ptmrList); + if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) + { + DPRINT("Clearing Bit %d)\n", pTmr->nID); + IntLockWindowlessTimerBitmap(); + RtlClearBit(&WindowLessTimersBitMap, pTmr->nID); + IntUnlockWindowlessTimerBitmap(); + } + UserDereferenceObject(pTmr); + Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer); } - return FALSE; + if (!Ret) DPRINT1("Warning unable to delete timer\n"); + + return Ret; } PTIMER @@ -84,7 +118,7 @@ FindTimer(PWINDOW_OBJECT Window, { PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr, RetTmr = NULL; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if (!pTmr) break; @@ -104,7 +138,7 @@ FindTimer(PWINDOW_OBJECT Window, pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); return RetTmr; } @@ -115,7 +149,7 @@ FindSystemTimer(PMSG pMsg) { PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if (!pTmr) break; @@ -127,7 +161,7 @@ FindSystemTimer(PMSG pMsg) pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); return pTmr; } @@ -144,7 +178,7 @@ ValidateTimerCallback(PTHREADINFO pti, if (!pTmr) return FALSE; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if ( (lParam == (LPARAM)pTmr->pfn) && @@ -155,7 +189,7 @@ ValidateTimerCallback(PTHREADINFO pti, pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); if (!pTmr) return FALSE; @@ -197,9 +231,15 @@ IntSetTimer( PWINDOW_OBJECT Window, Elapse = 10; } - if ((Window == NULL) && (!(Type & TMRF_SYSTEM))) + if ((Window) && (IDEvent == 0)) + IDEvent = 1; + + pTmr = FindTimer(Window, IDEvent, Type, FALSE); + + if ((!pTmr) && (Window == NULL) && (!(Type & TMRF_SYSTEM))) { IntLockWindowlessTimerBitmap(); + IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex); if (IDEvent == (UINT_PTR) -1) @@ -210,26 +250,26 @@ IntSetTimer( PWINDOW_OBJECT Window, return 0; } - HintIndex = ++IDEvent; - IntUnlockWindowlessTimerBitmap(); Ret = IDEvent; + //HintIndex = IDEvent + 1; + IntUnlockWindowlessTimerBitmap(); } - pTmr = FindTimer(Window, IDEvent, Type, FALSE); if (!pTmr) { pTmr = CreateTimer(); if (!pTmr) return 0; - if (Window && (Type & TMRF_TIFROMWND)) - pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread; - else - { - if (Type & TMRF_RIT) - pTmr->pti = ptiRawInput; - else - pTmr->pti = PsGetCurrentThreadWin32Thread(); + if (Window && (Type & TMRF_TIFROMWND)) + pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread; + else + { + if (Type & TMRF_RIT) + pTmr->pti = ptiRawInput; + else + pTmr->pti = PsGetCurrentThreadWin32Thread(); } + pTmr->pWnd = Window; pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; @@ -237,12 +277,10 @@ IntSetTimer( PWINDOW_OBJECT Window, pTmr->nID = IDEvent; pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode. } - - pTmr->cmsCountdown = Elapse; - pTmr->cmsRate = Elapse; - if (pTmr->flags & TMRF_DELETEPENDING) + else { - pTmr->flags &= ~TMRF_DELETEPENDING; + pTmr->cmsCountdown = Elapse; + pTmr->cmsRate = Elapse; } ASSERT(MasterTimer != NULL); @@ -306,7 +344,7 @@ PostTimerMessages(PWINDOW_OBJECT Window) pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { @@ -329,7 +367,7 @@ PostTimerMessages(PWINDOW_OBJECT Window) pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); return Hit; } @@ -342,10 +380,11 @@ ProcessTimers(VOID) LONG Time; PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr; + LONG TimerCount = 0; if (!pTmr) return; - UserEnterExclusive(); + TimerEnterExclusive(); KeQueryTickCount(&TickCount); Time = MsqCalculateMessageTime(&TickCount); @@ -354,6 +393,7 @@ ProcessTimers(VOID) do { + TimerCount++; if (pTmr->flags & TMRF_WAITING) { pLE = pTmr->ptmrList.Flink; @@ -391,25 +431,7 @@ ProcessTimers(VOID) } } } - if (pTmr->flags & TMRF_DELETEPENDING) - { - DPRINT("Removing Timer %x from List\n", pTmr); - - /* FIXME: Fix this!!!! */ -/* - if (!pTmr->pWnd) - { - DPRINT1("Clearing Bits for WindowLess Timer\n"); - IntLockWindowlessTimerBitmap(); - RtlSetBits(&WindowLessTimersBitMap, pTmr->nID, 1); - IntUnlockWindowlessTimerBitmap(); - } -*/ - RemoveEntryList(&pTmr->ptmrList); - UserDeleteObject( UserHMGetHandle(pTmr), otTimer); - } - else - pTmr->cmsCountdown = pTmr->cmsRate; + pTmr->cmsCountdown = pTmr->cmsRate; } else pTmr->cmsCountdown -= Time - TimeLast; @@ -425,7 +447,8 @@ ProcessTimers(VOID) TimeLast = Time; - UserLeave(); + TimerLeave(); + DPRINT("TimerCount = %d\n", TimerCount); } // @@ -524,6 +547,33 @@ if (Ret == 0) ASSERT(FALSE); return Ret; } +BOOL FASTCALL +DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) +{ + PLIST_ENTRY pLE; + PTIMER pTmr = FirstpTmr; + BOOL TimersRemoved = FALSE; + + if ((FirstpTmr == NULL) || (Window == NULL)) + return FALSE; + + TimerEnterExclusive(); + + do + { + if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window)) + { + TimersRemoved = RemoveTimer(pTmr); + } + pLE = pTmr->ptmrList.Flink; + pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); + } while (pTmr != FirstpTmr); + + TimerLeave(); + + return TimersRemoved; +} + BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti) { @@ -534,26 +584,23 @@ DestroyTimersForThread(PTHREADINFO pti) if (FirstpTmr == NULL) return FALSE; - KeEnterCriticalRegion(); + TimerEnterExclusive(); do { if ((pTmr) && (pTmr->pti == pti)) { - pTmr->flags &= ~TMRF_READY; - pTmr->flags |= TMRF_DELETEPENDING; - TimersRemoved = TRUE; + TimersRemoved = RemoveTimer(pTmr); } pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); - KeLeaveCriticalRegion(); + TimerLeave(); return TimersRemoved; } - BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) { @@ -561,14 +608,13 @@ IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) DPRINT("IntKillTimer Window %x id %p systemtimer %s\n", Window, IDEvent, SystemTimer ? "TRUE" : "FALSE"); - if (IDEvent == 0) - return FALSE; + if ((Window) && (IDEvent == 0)) + IDEvent = 1; pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0, TRUE); return pTmr ? TRUE : FALSE; } - // // // Old Kill Timer @@ -661,16 +707,19 @@ NtUserSetTimer TIMERPROC lpTimerFunc ) { + PWINDOW_OBJECT Window; DECLARE_RETURN(UINT_PTR); DPRINT("Enter NtUserSetTimer\n"); UserEnterExclusive(); + Window = UserGetWindowObject(hWnd); + UserLeave(); - RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, 0)); + RETURN(IntSetTimer(Window, nIDEvent, uElapse, lpTimerFunc, TMRF_TIFROMWND)); CLEANUP: DPRINT("Leave NtUserSetTimer, ret=%i\n", _ret_); - UserLeave(); + END_CLEANUP; } @@ -688,14 +737,13 @@ NtUserKillTimer DPRINT("Enter NtUserKillTimer\n"); UserEnterExclusive(); - Window = UserGetWindowObject(hWnd); + UserLeave(); RETURN(IntKillTimer(Window, uIDEvent, FALSE)); CLEANUP: DPRINT("Leave NtUserKillTimer, ret=%i\n", _ret_); - UserLeave(); END_CLEANUP; } @@ -712,14 +760,12 @@ NtUserSetSystemTimer( DECLARE_RETURN(UINT_PTR); DPRINT("Enter NtUserSetSystemTimer\n"); - UserEnterExclusive(); // This is wrong, lpTimerFunc is NULL! RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM)); CLEANUP: DPRINT("Leave NtUserSetSystemTimer, ret=%i\n", _ret_); - UserLeave(); END_CLEANUP; } diff --git a/subsystems/win32/win32k/ntuser/window.c b/subsystems/win32/win32k/ntuser/window.c index e9f64d292f4..5379fcbc3ed 100644 --- a/subsystems/win32/win32k/ntuser/window.c +++ b/subsystems/win32/win32k/ntuser/window.c @@ -96,6 +96,8 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd) ASSERT(Window->head.cLockObj >= 0); Window->head.cLockObj++; + + ASSERT(Window->Wnd); } return Window; } @@ -130,6 +132,9 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd) } ASSERT(Window->head.cLockObj >= 0); + + ASSERT(Window->Wnd); + return Window; } @@ -163,20 +168,12 @@ IntIsWindow(HWND hWnd) -/* - Caller must NOT dereference retval! - But if caller want the returned value to persist spanning a co_ call, - it must reference the value (because the owner is not garanteed to - exist just because the owned window exist)! -*/ PWINDOW_OBJECT FASTCALL IntGetParent(PWINDOW_OBJECT Wnd) { - if (!Wnd->Wnd) return NULL; - if (Wnd->Wnd->style & WS_POPUP) { - return UserGetWindowObject(Wnd->hOwner); + return Wnd->spwndOwner; } else if (Wnd->Wnd->style & WS_CHILD) { @@ -187,20 +184,6 @@ IntGetParent(PWINDOW_OBJECT Wnd) } -/* - Caller must NOT dereference retval! - But if caller want the returned value to persist spanning a co_ call, - it must reference the value (because the owner is not garanteed to - exist just because the owned window exist)! -*/ -PWINDOW_OBJECT FASTCALL -IntGetOwner(PWINDOW_OBJECT Wnd) -{ - return UserGetWindowObject(Wnd->hOwner); -} - - - /* * IntWinListChildren * @@ -265,7 +248,7 @@ static void IntSendDestroyMsg(HWND hWnd) // USER_REFERENCE_ENTRY Ref; // UserRefObjectCo(Window, &Ref); - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd); } @@ -424,7 +407,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window, if(BelongsToThreadData) co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0); } - MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf); + DestroyTimersForWindow(ThreadData, Window); HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too! /* flush the message queue */ @@ -1091,26 +1074,19 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) if(!Wnd) return NULL; - WndOldOwner = IntGetWindowObject(Wnd->hOwner); - if (WndOldOwner) - { - ret = WndOldOwner->hSelf; - UserDereferenceObject(WndOldOwner); - } - else - { - ret = 0; - } + WndOldOwner = Wnd->spwndOwner; + + ret = WndOldOwner ? WndOldOwner->hSelf : 0; if((WndNewOwner = UserGetWindowObject(hWndNewOwner))) { - Wnd->hOwner = hWndNewOwner; - Wnd->Wnd->spwndOwner = WndNewOwner->Wnd; + Wnd->spwndOwner= WndNewOwner; + Wnd->Wnd->spwndOwner = WndNewOwner->Wnd; } else { - Wnd->hOwner = NULL; - Wnd->Wnd->spwndOwner = NULL; + Wnd->spwndOwner = NULL; + Wnd->Wnd->spwndOwner = NULL; } UserDereferenceObject(Wnd); @@ -1279,31 +1255,6 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd) Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL; } -BOOL FASTCALL -IntAnyPopup(VOID) -{ - PWINDOW_OBJECT Window, Child; - - if(!(Window = UserGetWindowObject(IntGetDesktopWindow()))) - { - return FALSE; - } - - for(Child = Window->spwndChild; Child; Child = Child->spwndNext) - { - if(Child->hOwner && Child->Wnd->style & WS_VISIBLE) - { - /* - * The desktop has a popup window if one of them has - * an owner window and is visible - */ - return TRUE; - } - } - - return FALSE; -} - BOOL FASTCALL IntIsWindowInDestroy(PWINDOW_OBJECT Window) { @@ -1511,7 +1462,7 @@ NtUserBuildHwndList( Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry); ASSERT(Window); - if(bChildren || Window->hOwner != NULL) + if(bChildren || Window->spwndOwner != NULL) { if(dwCount < *pBufSize && pWnd) { @@ -1603,244 +1554,125 @@ NtUserChildWindowFromPointEx(HWND hwndParent, return Ret; } - -/* - * calculates the default position of a window - */ -BOOL FASTCALL -IntCalcDefPosSize(PWINDOW_OBJECT Parent, RECTL *rc, BOOL IncPos) +void FASTCALL +IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* dwShowMode) { - SIZE Sz; - PMONITOR pMonitor; - POINT Pos = {0, 0}; - - pMonitor = IntGetPrimaryMonitor(); +#define IS_DEFAULT(x) ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000) - if(Parent != NULL) + /* default positioning for overlapped windows */ + if(!(Cs->style & (WS_POPUP | WS_CHILD))) { - RECTL_bIntersectRect(rc, rc, &pMonitor->rcMonitor); + RECTL rc, WorkArea; + PRTL_USER_PROCESS_PARAMETERS ProcessParams; - if(IncPos) + UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0); + + rc = WorkArea; + ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters; + + if (IS_DEFAULT(Cs->x)) { - Pos.x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME)); - Pos.y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME)); - if (Pos.x > ((rc->right - rc->left) / 4) || - Pos.y > ((rc->bottom - rc->top) / 4)) - { - /* reset counter and position */ - Pos.x = 0; - Pos.y = 0; - pMonitor->cWndStack = 0; - } - pMonitor->cWndStack++; + if (!IS_DEFAULT(Cs->y)) *dwShowMode = Cs->y; + + if(ProcessParams->WindowFlags & STARTF_USEPOSITION) + { + Cs->x = ProcessParams->StartingX; + Cs->y = ProcessParams->StartingY; + } + else + { + Cs->x = WorkArea.left; + Cs->y = WorkArea.top; + } + } + + if (IS_DEFAULT(Cs->cx)) + { + if (ProcessParams->WindowFlags & STARTF_USEPOSITION) + { + Cs->cx = ProcessParams->CountX; + Cs->cy = ProcessParams->CountY; + } + else + { + Cs->cx = (WorkArea.right - WorkArea.left) * 3 / 4 - Cs->x; + Cs->cy = (WorkArea.bottom - WorkArea.top) * 3 / 4 - Cs->y; + } + } + /* neither x nor cx are default. Check the y values . + * In the trace we see Outlook and Outlook Express using + * cy set to CW_USEDEFAULT when opening the address book. + */ + else if (IS_DEFAULT(Cs->cy)) + { + DPRINT("Strange use of CW_USEDEFAULT in nHeight\n"); + Cs->cy = (WorkArea.bottom - WorkArea.top) * 3 / 4 - Cs->y; } - Pos.x += rc->left; - Pos.y += rc->top; } else { - Pos.x = rc->left; - Pos.y = rc->top; + /* if CW_USEDEFAULT is set for non-overlapped windows, both values are set to zero */ + if(IS_DEFAULT(Cs->x)) + { + Cs->x = 0; + Cs->y = 0; + } + if(IS_DEFAULT(Cs->cx)) + { + Cs->cx = 0; + Cs->cy = 0; + } } - Sz.cx = EngMulDiv(rc->right - rc->left, 3, 4); - Sz.cy = EngMulDiv(rc->bottom - rc->top, 3, 4); - - rc->left = Pos.x; - rc->top = Pos.y; - rc->right = rc->left + Sz.cx; - rc->bottom = rc->top + Sz.cy; - return TRUE; +#undef IS_DEFAULT } - -/* - * @implemented - */ -PWND APIENTRY -co_IntCreateWindowEx(DWORD dwExStyle, - PUNICODE_STRING ClassName, - PLARGE_STRING WindowName, - DWORD dwStyle, - LONG x, - LONG y, - LONG nWidth, - LONG nHeight, - HWND hWndParent, - HMENU hMenu, - HINSTANCE hInstance, - LPVOID lpParam, - DWORD dwShowMode, - BOOL bUnicodeWindow) +/* Allocates and initializes a window*/ +PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, + PLARGE_STRING WindowName, + PCLS Class, + PWINDOW_OBJECT ParentWindow, + PWINDOW_OBJECT OwnerWindow) { - PWINSTATION_OBJECT WinSta; PWND Wnd = NULL; - PCLS *ClassLink, Class = NULL; - RTL_ATOM ClassAtom; - PWINDOW_OBJECT Window = NULL; - PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow; - HWND ParentWindowHandle = NULL; - HWND OwnerWindowHandle; - PMENU_OBJECT SystemMenu; + PWINDOW_OBJECT Window; HWND hWnd; - POINT Pos; - SIZE Size; - PTHREADINFO ti = NULL; -#if 0 - - POINT MaxSize, MaxPos, MinTrack, MaxTrack; -#else - - POINT MaxPos; -#endif - CREATESTRUCTW Cs; - CBT_CREATEWNDW CbtCreate; - LRESULT Result; + PTHREADINFO pti = NULL; + PMENU_OBJECT SystemMenu; BOOL MenuChanged; - DECLARE_RETURN(PWND); - BOOL HasOwner; - USER_REFERENCE_ENTRY ParentRef, Ref; - PTHREADINFO pti; + BOOL bUnicodeWindow; pti = PsGetCurrentThreadWin32Thread(); - if (pti->rpdesk) - { - ParentWindowHandle = pti->rpdesk->DesktopWindow; - } - - - if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED )) - { - UserRegisterSystemClasses(); - } - - OwnerWindowHandle = NULL; - - DPRINT("co_IntCreateWindowEx %wZ\n", ClassName); - - if (hWndParent == HWND_MESSAGE) - { - /* - * native ole32.OleInitialize uses HWND_MESSAGE to create the - * message window (style: WS_POPUP|WS_DISABLED) - */ - ParentWindowHandle = IntGetMessageWindow(); - DPRINT("Parent is HWND_MESSAGE 0x%x\n", ParentWindowHandle); - } - else if (hWndParent) - { - if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) - { //temp hack - PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root; - if (Par && (Root = UserGetAncestor(Par, GA_ROOT))) - OwnerWindowHandle = Root->hSelf; - } - else - ParentWindowHandle = hWndParent; - } - else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD) - { - SetLastWin32Error(ERROR_TLW_WITH_WSCHILD); - RETURN( (PWND)0); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ - } - - if (ParentWindowHandle) - { - ParentWindow = UserGetWindowObject(ParentWindowHandle); - - if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef); - } + /* Automatically add WS_EX_WINDOWEDGE */ + if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) || + ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) && + (Cs->style & (WS_DLGFRAME | WS_THICKFRAME)))) + Cs->dwExStyle |= WS_EX_WINDOWEDGE; else - { - ParentWindow = NULL; - } + Cs->dwExStyle &= ~WS_EX_WINDOWEDGE; - /* FIXME: parent must belong to the current process */ + /* Is it a unicode window? */ + bUnicodeWindow =!(Cs->dwExStyle & WS_EX_SETANSICREATOR); + Cs->dwExStyle &= ~WS_EX_SETANSICREATOR; - /* Check the window station. */ - ti = GetW32ThreadInfo(); - if (ti == NULL || pti->rpdesk == NULL) - { - DPRINT1("Thread is not attached to a desktop! Cannot create window!\n"); - RETURN( (PWND)0); - } - - /* Check the class. */ - - DPRINT("Class %wZ\n", ClassName); - - ClassAtom = IntGetClassAtom(ClassName, - hInstance, - ti->ppi, - &Class, - &ClassLink); - - if (ClassAtom == (RTL_ATOM)0) - { - if (IS_ATOM(ClassName->Buffer)) - { - DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer); - } - else - { - DPRINT1("Class \"%wZ\" not found\n", ClassName); - } - - SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS); - RETURN((PWND)0); - } - DPRINT("ClassAtom %x\n", ClassAtom); - Class = IntReferenceClass(Class, - ClassLink, - pti->rpdesk); - if (Class == NULL) - { - DPRINT1("Failed to reference window class!\n"); - RETURN(NULL); - } - - WinSta = pti->rpdesk->rpwinstaParent; - - //FIXME: Reference thread/desktop instead - ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); - - /* Create the window object. */ + /* Allocate the new window */ Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable, pti->rpdesk, (PHANDLE)&hWnd, otWindow, sizeof(WINDOW_OBJECT)); - if (Window) - { - Window->Wnd = DesktopHeapAlloc(pti->rpdesk, - sizeof(WND) + Class->cbwndExtra); - if (!Window->Wnd) - goto AllocErr; - RtlZeroMemory(Window->Wnd, - sizeof(WND) + Class->cbwndExtra); - Window->Wnd->head.h = hWnd; - Wnd = Window->Wnd; - Wnd->fnid = 0; - Wnd->head.pti = ti; - Wnd->head.rpdesk = pti->rpdesk; - Wnd->hWndLastActive = hWnd; - Wnd->state2 |= WNDS2_WIN40COMPAT; + Wnd = DesktopHeapAlloc(pti->rpdesk, sizeof(WND) + Class->cbwndExtra); + + if(!Window || !Wnd) + { + goto AllocError; } + RtlZeroMemory(Wnd, sizeof(WND) + Class->cbwndExtra); + DPRINT("Created object with handle %X\n", hWnd); - if (!Window) - { -AllocErr: - ObDereferenceObject(WinSta); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - RETURN( (PWND)0); - } - - UserRefObjectCo(Window, &Ref); - - ObDereferenceObject(WinSta); if (NULL == pti->rpdesk->DesktopWindow) { @@ -1852,39 +1684,33 @@ AllocErr: /* * Fill out the structure describing it. */ - Window->pti = ti; - Wnd->pcls = Class; - Class = NULL; - - Window->SystemMenu = (HMENU)0; - Wnd->IDMenu = 0; - Wnd->hModule = hInstance; + Window->Wnd = Wnd; + Window->pti = pti; Window->hSelf = hWnd; + Window->spwndParent = ParentWindow; + Window->spwndOwner = OwnerWindow; + + Wnd->head.h = hWnd; + Wnd->head.pti = pti; + Wnd->head.rpdesk = pti->rpdesk; + Wnd->fnid = 0; + Wnd->hWndLastActive = hWnd; + Wnd->state2 |= WNDS2_WIN40COMPAT; + Wnd->pcls = Class; + Wnd->hModule = Cs->hInstance; + Wnd->style = Cs->style & ~WS_VISIBLE; + Wnd->ExStyle = Cs->dwExStyle; + Wnd->cbwndExtra = Wnd->pcls->cbwndExtra; + Wnd->spwndOwner = OwnerWindow ? OwnerWindow->Wnd : NULL; + Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL; IntReferenceMessageQueue(Window->pti->MessageQueue); - Window->spwndParent = ParentWindow; - Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL; - if (Wnd->spwndParent != NULL && hWndParent != 0) + if (Wnd->spwndParent != NULL && Cs->hwndParent != 0) { Wnd->HideFocus = Wnd->spwndParent->HideFocus; Wnd->HideAccel = Wnd->spwndParent->HideAccel; } - if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle))) - { - Window->hOwner = OwnerWindowHandle; - Wnd->spwndOwner = OwnerWindow->Wnd; - HasOwner = TRUE; - } - else - { - Window->hOwner = NULL; - Wnd->spwndOwner = NULL; - HasOwner = FALSE; - } - - Wnd->dwUserData = 0; - if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC) Wnd->state |= WNDS_SERVERSIDEWINDOWPROC; @@ -1929,15 +1755,15 @@ AllocErr: WndProc, unless the following overriding conditions occur: */ if ( !bUnicodeWindow && - ( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON] || - ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX] || - ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] || - ClassAtom == gpsi->atomSysClass[ICLS_DIALOG] || - ClassAtom == gpsi->atomSysClass[ICLS_EDIT] || - ClassAtom == gpsi->atomSysClass[ICLS_IME] || - ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX] || - ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] || - ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) ) + ( Class->atomClassName == gpsi->atomSysClass[ICLS_BUTTON] || + Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX] || + Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOLBOX] || + Class->atomClassName == gpsi->atomSysClass[ICLS_DIALOG] || + Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT] || + Class->atomClassName == gpsi->atomSysClass[ICLS_IME] || + Class->atomClassName == gpsi->atomSysClass[ICLS_LISTBOX] || + Class->atomClassName == gpsi->atomSysClass[ICLS_MDICLIENT] || + Class->atomClassName == gpsi->atomSysClass[ICLS_STATIC] ) ) { // Override Class and set the window Ansi WndProc. Wnd->state |= WNDS_ANSIWINDOWPROC; Wnd->Unicode = FALSE; @@ -1949,74 +1775,61 @@ AllocErr: } } - Window->spwndChild = NULL; - Window->spwndPrev = NULL; - Window->spwndNext = NULL; + /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx, + then my testing shows that windows (2k and XP) creates a CallProc for it immediately + Dont understand why it does this. */ + if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT]) + { + PCALLPROCDATA CallProc; + //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi); + CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi); - Wnd->spwndNext = NULL; - Wnd->spwndPrev = NULL; - Wnd->spwndChild = NULL; - - Wnd->cbwndExtra = Wnd->pcls->cbwndExtra; + if (!CallProc) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd); + } + else + { + UserAddCallProcToClass(Wnd->pcls, CallProc); + } + } InitializeListHead(&Wnd->PropListHead); - if ( NULL != WindowName->Buffer && WindowName->Length > 0 ) + if ( WindowName->Buffer != NULL && WindowName->Length > 0 ) { Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk, - WindowName->Length + sizeof(UNICODE_NULL)); + WindowName->Length + sizeof(UNICODE_NULL)); if (Wnd->strName.Buffer == NULL) { - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - RETURN( (PWND)0); + goto AllocError; } + RtlCopyMemory(Wnd->strName.Buffer, WindowName->Buffer, WindowName->Length); Wnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0'; - _SEH2_TRY - { - RtlCopyMemory(Wnd->strName.Buffer, - WindowName->Buffer, - WindowName->Length); - Wnd->strName.Length = WindowName->Length; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - WindowName->Length = 0; - Wnd->strName.Buffer[0] = L'\0'; - } - _SEH2_END; + Wnd->strName.Length = WindowName->Length; } - /* - * This has been tested for WS_CHILD | WS_VISIBLE. It has not been - * tested for WS_POPUP - */ - if ((dwExStyle & WS_EX_DLGMODALFRAME) || - ((!(dwExStyle & WS_EX_STATICEDGE)) && - (dwStyle & (WS_DLGFRAME | WS_THICKFRAME)))) - dwExStyle |= WS_EX_WINDOWEDGE; - else - dwExStyle &= ~WS_EX_WINDOWEDGE; - - dwExStyle &= ~WS_EX_SETANSICREATOR; - - Wnd->style = dwStyle & ~WS_VISIBLE; - /* Correct the window style. */ if ((Wnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) { Wnd->style |= WS_CLIPSIBLINGS; - DPRINT("3: Style is now %lx\n", dwStyle); if (!(Wnd->style & WS_POPUP)) { Wnd->style |= WS_CAPTION; Window->state |= WINDOWOBJECT_NEED_SIZE; - DPRINT("4: Style is now %lx\n", dwStyle); } } + if ((Wnd->ExStyle & WS_EX_DLGMODALFRAME) || + (Wnd->style & (WS_DLGFRAME | WS_THICKFRAME))) + Wnd->ExStyle |= WS_EX_WINDOWEDGE; + else + Wnd->ExStyle &= ~WS_EX_WINDOWEDGE; + /* create system menu */ - if((dwStyle & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION) + if((Cs->style & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION) { SystemMenu = IntGetSystemMenu(Window, TRUE, TRUE); if(SystemMenu) @@ -2027,13 +1840,15 @@ AllocErr: } /* Set the window menu */ - if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) + if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) { - if (hMenu) - IntSetMenu(Window, hMenu, &MenuChanged); + if (Cs->hMenu) + IntSetMenu(Window, Cs->hMenu, &MenuChanged); else if (Wnd->pcls->lpszMenuName) // Take it from the parent. { UNICODE_STRING MenuName; + HMENU hMenu; + if (IS_INTRESOURCE(Wnd->pcls->lpszMenuName)) { MenuName.Length = 0; @@ -2049,7 +1864,7 @@ AllocErr: } } else // Not a child - Wnd->IDMenu = (UINT) hMenu; + Wnd->IDMenu = (UINT) Cs->hMenu; /* Insert the window into the thread's window list. */ InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry); @@ -2064,163 +1879,138 @@ AllocErr: DceAllocDCE(Window, DCE_WINDOW_DC); } - Pos.x = x; - Pos.y = y; - Size.cx = nWidth; - Size.cy = nHeight; + return Window; - Wnd->ExStyle = dwExStyle; +AllocError: - /* call hook */ - Cs.lpCreateParams = lpParam; - Cs.hInstance = hInstance; - Cs.hMenu = hMenu; - Cs.hwndParent = hWndParent; //Pass the original Parent handle! - Cs.cx = Size.cx; - Cs.cy = Size.cy; - Cs.x = Pos.x; - Cs.y = Pos.y; - Cs.style = Wnd->style; -// Cs.lpszName = (LPCWSTR) WindowName->Buffer; -// Cs.lpszClass = (LPCWSTR) ClassName->Buffer; - Cs.lpszName = (LPCWSTR) WindowName; - Cs.lpszClass = (LPCWSTR) ClassName; - Cs.dwExStyle = dwExStyle; - CbtCreate.lpcs = &Cs; + if(Window) + UserDereferenceObject(Window); + + if(Wnd) + DesktopHeapFree(Wnd->head.rpdesk, Wnd); + + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + return NULL; +} + +/* + * @implemented + */ +PWND FASTCALL +co_UserCreateWindowEx(CREATESTRUCTW* Cs, + PUNICODE_STRING ClassName, + PLARGE_STRING WindowName) +{ + PWINDOW_OBJECT Window = NULL, ParentWindow = NULL, OwnerWindow; + HWND hWnd, hWndParent, hWndOwner; + DWORD dwStyle; + PWINSTATION_OBJECT WinSta; + PWND Wnd = NULL; + PCLS Class = NULL; + SIZE Size; + POINT MaxPos; + CBT_CREATEWNDW CbtCreate; + LRESULT Result; + USER_REFERENCE_ENTRY ParentRef, Ref; + PTHREADINFO pti; + DWORD dwShowMode = SW_SHOW; + DECLARE_RETURN(PWND); + + /* Get the current window station and reference it */ + pti = GetW32ThreadInfo(); + if (pti == NULL || pti->rpdesk == NULL) + { + DPRINT1("Thread is not attached to a desktop! Cannot create window!\n"); + return NULL; //There is nothing to cleanup + } + WinSta = pti->rpdesk->rpwinstaParent; + ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); + + /* Get the class and reference it*/ + Class = IntGetAndReferenceClass(ClassName, Cs->hInstance); + if(!Class) + { + DPRINT1("Failed to find class %wZ\n", ClassName); + RETURN(NULL); + } + + /* Now find the parent and the owner window */ + hWndParent = IntGetDesktopWindow(); + hWndOwner = NULL; + + if (Cs->hwndParent == HWND_MESSAGE) + { + Cs->hwndParent = hWndParent = IntGetMessageWindow(); + } + else if (Cs->hwndParent) + { + if ((Cs->style & (WS_CHILD|WS_POPUP)) != WS_CHILD) + hWndOwner = Cs->hwndParent; + else + hWndParent = Cs->hwndParent; + } + else if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) + { + DPRINT1("Cannot create a child window without a parrent!\n"); + SetLastWin32Error(ERROR_TLW_WITH_WSCHILD); + RETURN(NULL); /* WS_CHILD needs a parent, but WS_POPUP doesn't */ + } + + ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL; + OwnerWindow = hWndOwner ? UserGetWindowObject(hWndOwner): NULL; + + /* FIXME: is this correct?*/ + if(OwnerWindow) + OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT); + + /* Fix the position and the size of the window */ + if (ParentWindow) + { + UserRefObjectCo(ParentWindow, &ParentRef); + IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode); + } + + /* Allocate and initialize the new window */ + Window = IntCreateWindow(Cs, + WindowName, + Class, + ParentWindow, + OwnerWindow); + if(!Window) + { + DPRINT1("IntCreateWindow failed!\n"); + RETURN(0); + } + + Wnd = Window->Wnd; + hWnd = Window->hSelf; + + UserRefObjectCo(Window, &Ref); + ObDereferenceObject(WinSta); + + /* Call the WH_CBT hook */ + dwStyle = Cs->style; + Cs->style = Wnd->style; /* HCBT_CREATEWND needs the real window style */ + CbtCreate.lpcs = Cs; CbtCreate.hwndInsertAfter = HWND_TOP; if (ISITHOOKED(WH_CBT)) { if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate)) { - /* FIXME - Delete window object and remove it from the thread windows list */ - /* FIXME - delete allocated DCE */ - DPRINT1("CBT-hook returned !0\n"); + DPRINT1("HCBT_CREATEWND hook failed!\n"); RETURN( (PWND) NULL); } } - x = Cs.x; - y = Cs.y; - nWidth = Cs.cx; - nHeight = Cs.cy; + Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/ - Cs.style = dwStyle; -// FIXME: Need to set the Z order in the window link list if the hook callback changed it! -// hwndInsertAfter = CbtCreate.hwndInsertAfter; + /* Send the WM_GETMINMAXINFO message*/ + Size.cx = Cs->cx; + Size.cy = Cs->cy; - /* default positioning for overlapped windows */ - if(!(Wnd->style & (WS_POPUP | WS_CHILD))) - { - RECTL rc, WorkArea; - PRTL_USER_PROCESS_PARAMETERS ProcessParams; - BOOL CalculatedDefPosSize = FALSE; - - UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0); - - rc = WorkArea; - ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters; - - if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16) - { - CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, &rc, TRUE); - - if(ProcessParams->WindowFlags & STARTF_USEPOSITION) - { - ProcessParams->WindowFlags &= ~STARTF_USEPOSITION; - Pos.x = WorkArea.left + ProcessParams->StartingX; - Pos.y = WorkArea.top + ProcessParams->StartingY; - } - else - { - Pos.x = rc.left; - Pos.y = rc.top; - } - -/* - According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and - y is something else. and Quote! - */ - -/* Never believe Microsoft's documentation... CreateWindowEx doc says - * that if an overlapped window is created with WS_VISIBLE style bit - * set and the x parameter is set to CW_USEDEFAULT, the system ignores - * the y parameter. However, disassembling NT implementation (WIN32K.SYS) - * reveals that - * - * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16 - * 2) it does not ignore the y parameter as the docs claim; instead, it - * uses it as second parameter to ShowWindow() unless y is either - * CW_USEDEFAULT or CW_USEDEFAULT16. - * - * The fact that we didn't do 2) caused bogus windows pop up when wine - * was running apps that were using this obscure feature. Example - - * calc.exe that comes with Win98 (only Win98, it's different from - * the one that comes with Win95 and NT) - */ - if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16) - { - dwShowMode = y; - } - } - if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16) - { - if(!CalculatedDefPosSize) - { - IntCalcDefPosSize(ParentWindow, &rc, FALSE); - } - if(ProcessParams->WindowFlags & STARTF_USESIZE) - { - ProcessParams->WindowFlags &= ~STARTF_USESIZE; - Size.cx = ProcessParams->CountX; - Size.cy = ProcessParams->CountY; - } - else - { - Size.cx = rc.right - rc.left; - Size.cy = rc.bottom - rc.top; - } - - /* move the window if necessary */ - if(Pos.x > rc.left) - Pos.x = max(rc.left, 0); - if(Pos.y > rc.top) - Pos.y = max(rc.top, 0); - } - } - else - { - /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */ - if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16) - { - Pos.x = 0; - Pos.y = 0; - } - if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16) - { - Size.cx = 0; - Size.cy = 0; - } - } - - /* Initialize the window dimensions. */ - Wnd->rcWindow.left = Pos.x; - Wnd->rcWindow.top = Pos.y; - Wnd->rcWindow.right = Pos.x + Size.cx; - Wnd->rcWindow.bottom = Pos.y + Size.cy; - if (0 != (Wnd->style & WS_CHILD) && ParentWindow) - { - RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left, - ParentWindow->Wnd->rcClient.top); - } - Wnd->rcClient = Wnd->rcWindow; - - /* - * Get the size and position of the window. - */ if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD))) { POINT MaxSize, MaxPos, MinTrack, MaxTrack; - /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */ co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack, &MaxTrack); if (Size.cx > MaxTrack.x) Size.cx = MaxTrack.x; if (Size.cy > MaxTrack.y) Size.cy = MaxTrack.y; @@ -2228,50 +2018,20 @@ AllocErr: if (Size.cy < MinTrack.y) Size.cy = MinTrack.y; } - if (Size.cx < 0) Size.cx = 0; - if (Size.cy < 0) Size.cy = 0; - - Wnd->rcWindow.left = Pos.x; - Wnd->rcWindow.top = Pos.y; - Wnd->rcWindow.right = Pos.x + Size.cx; - Wnd->rcWindow.bottom = Pos.y + Size.cy; + Wnd->rcWindow.left = Cs->x; + Wnd->rcWindow.top = Cs->y; + Wnd->rcWindow.right = Cs->x + Size.cx; + Wnd->rcWindow.bottom = Cs->y + Size.cy; if (0 != (Wnd->style & WS_CHILD) && ParentWindow) { - RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left, - ParentWindow->Wnd->rcClient.top); + RECTL_vOffsetRect(&Wnd->rcWindow, + ParentWindow->Wnd->rcClient.left, + ParentWindow->Wnd->rcClient.top); } Wnd->rcClient = Wnd->rcWindow; - /* FIXME: Initialize the window menu. */ - - /* Send a NCCREATE message. */ - DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent); - DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, Size.cx, Size.cy); - DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n"); - Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) &Cs); - if (!Result) - { - /* FIXME: Cleanup. */ - DPRINT1("IntCreateWindowEx(): NCCREATE message failed. No cleanup performed!\n"); - RETURN((PWND)0); - } - - /* Calculate the non-client size. */ - MaxPos.x = Window->Wnd->rcWindow.left; - MaxPos.y = Window->Wnd->rcWindow.top; - - - DPRINT("IntCreateWindowEx(): About to get non-client size.\n"); - /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */ - Result = co_WinPosGetNonClientSize(Window, - &Window->Wnd->rcWindow, - &Window->Wnd->rcClient); - - RECTL_vOffsetRect(&Window->Wnd->rcWindow, - MaxPos.x - Window->Wnd->rcWindow.left, - MaxPos.y - Window->Wnd->rcWindow.top); - + /* Link the window*/ if (NULL != ParentWindow) { /* link the window into the parent's child list */ @@ -2294,7 +2054,7 @@ AllocErr: { /* link window as top sibling (but after topmost siblings) */ PWINDOW_OBJECT InsertAfter, Sibling; - if (!(dwExStyle & WS_EX_TOPMOST)) + if (!(Cs->dwExStyle & WS_EX_TOPMOST)) { InsertAfter = NULL; Sibling = ParentWindow->spwndChild; @@ -2312,19 +2072,35 @@ AllocErr: IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */); } } + + /* Send the NCCREATE message */ + Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) Cs); + if (!Result) + { + DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n"); + RETURN((PWND)0); + } + + /* Send the WM_NCCALCSIZE message */ + MaxPos.x = Window->Wnd->rcWindow.left; + MaxPos.y = Window->Wnd->rcWindow.top; + + Result = co_WinPosGetNonClientSize(Window, &Wnd->rcWindow, &Wnd->rcClient); + + RECTL_vOffsetRect(&Wnd->rcWindow, MaxPos.x - Wnd->rcWindow.left, + MaxPos.y - Wnd->rcWindow.top); + /* Send the WM_CREATE message. */ - DPRINT("IntCreateWindowEx(): about to send CREATE message.\n"); - Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) &Cs); - + Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) Cs); if (Result == (LRESULT)-1) { - /* FIXME: Cleanup. */ - DPRINT1("IntCreateWindowEx(): send CREATE message failed. No cleanup performed!\n"); + DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); IntUnlinkWindow(Window); RETURN((PWND)0); } + /* Send the EVENT_OBJECT_CREATE event*/ IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0); /* By setting the flag below it can be examined to determine if the window @@ -2332,43 +2108,10 @@ AllocErr: from here the function has to succeed. */ Window->Wnd->state2 |= WNDS2_WMCREATEMSGPROCESSED; - /* Send move and size messages. */ + /* Send the WM_SIZE and WM_MOVE messages. */ if (!(Window->state & WINDOWOBJECT_NEED_SIZE)) { - LONG lParam; - - DPRINT("IntCreateWindow(): About to send WM_SIZE\n"); - - if ((Window->Wnd->rcClient.right - Window->Wnd->rcClient.left) < 0 || - (Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top) < 0) - { - DPRINT("Sending bogus WM_SIZE\n"); - } - - lParam = MAKE_LONG(Window->Wnd->rcClient.right - - Window->Wnd->rcClient.left, - Window->Wnd->rcClient.bottom - - Window->Wnd->rcClient.top); - co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED, - lParam); - - DPRINT("IntCreateWindow(): About to send WM_MOVE\n"); - - if (0 != (Wnd->style & WS_CHILD) && ParentWindow) - { - lParam = MAKE_LONG(Wnd->rcClient.left - ParentWindow->Wnd->rcClient.left, - Wnd->rcClient.top - ParentWindow->Wnd->rcClient.top); - } - else - { - lParam = MAKE_LONG(Wnd->rcClient.left, - Wnd->rcClient.top); - } - - co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam); - - /* Call WNDOBJ change procs */ - IntEngWindowChanged(Window, WOC_RGN_CLIENT); + co_WinPosSendSizeMove(Window); } /* Show or maybe minimize or maximize the window. */ @@ -2377,8 +2120,7 @@ AllocErr: RECTL NewPos; UINT16 SwFlag; - SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE : - SW_MAXIMIZE; + SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE; co_WinPosMinMaximize(Window, SwFlag, &NewPos); @@ -2386,32 +2128,25 @@ AllocErr: SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED : SWP_NOZORDER | SWP_FRAMECHANGED; - DPRINT("IntCreateWindow(): About to minimize/maximize\n"); - DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom); co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, SwFlag); } - /* Notify the parent window of a new child. */ + /* Send the WM_PARENTNOTIFY message */ if ((Wnd->style & WS_CHILD) && (!(Wnd->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow) { - DPRINT("IntCreateWindow(): About to notify parent\n"); co_IntSendMessage(ParentWindow->hSelf, WM_PARENTNOTIFY, MAKEWPARAM(WM_CREATE, Wnd->IDMenu), (LPARAM)Window->hSelf); } - if ((!hWndParent) && (!HasOwner)) + /* Notify the shell that a new window was created */ + if ((!hWndParent) && (!hWndOwner)) { - DPRINT("Sending CREATED notify\n"); co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd); } - else - { - DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner); - } /* Initialize and show the window's scrollbars */ if (Wnd->style & WS_VSCROLL) @@ -2423,14 +2158,14 @@ AllocErr: co_UserShowScrollBar(Window, SB_HORZ, TRUE); } - if (dwStyle & WS_VISIBLE) + /* Show the new window */ + if (Cs->style & WS_VISIBLE) { if (Wnd->style & WS_MAXIMIZE) dwShowMode = SW_SHOW; else if (Wnd->style & WS_MINIMIZE) dwShowMode = SW_SHOWMINIMIZED; - DPRINT("IntCreateWindow(): About to show window\n"); co_WinPosShowWindow(Window, dwShowMode); if (Wnd->ExStyle & WS_EX_MDICHILD) @@ -2441,49 +2176,26 @@ AllocErr: } } - /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx, - then my testing shows that windows (2k and XP) creates a CallProc for it immediately - Dont understand why it does this. */ - if (ClassAtom == gpsi->atomSysClass[ICLS_EDIT]) - { - PCALLPROCDATA CallProc; - //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi); - CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi); - - if (!CallProc) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd); - } - else - { - UserAddCallProcToClass(Wnd->pcls, CallProc); - } - } - - DPRINT("IntCreateWindow(): = %X\n", hWnd); - DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu); + DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd); RETURN( Wnd); CLEANUP: - if (!_ret_ && Window && Window->Wnd && ti) - co_UserDestroyWindow(Window); -// UserFreeWindowInfo(ti, Window); + if (!_ret_) + { + /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */ + if (Window) + co_UserDestroyWindow(Window); + else + IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi); + } + if (Window) { UserDerefObjectCo(Window); UserDereferenceObject(Window); } if (ParentWindow) UserDerefObjectCo(ParentWindow); - if (!_ret_ && ti != NULL) - { - if (Class != NULL) - { - IntDereferenceClass(Class, - ti->pDeskInfo, - ti->ppi); - } - } + END_CLEANUP; } @@ -2567,12 +2279,10 @@ NtUserCreateWindowEx( LARGE_STRING lstrWindowName; LARGE_STRING lstrClassName; UNICODE_STRING ustrClassName; + CREATESTRUCTW Cs; HWND hwnd = NULL; PWND pwnd; - DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight); - UserEnterExclusive(); - lstrWindowName.Buffer = NULL; lstrClassName.Buffer = NULL; @@ -2583,8 +2293,9 @@ NtUserCreateWindowEx( Status = ProbeAndCaptureLargeString(&lstrWindowName, plstrWindowName); if (!NT_SUCCESS(Status)) { + DPRINT1("NtUserCreateWindowEx: failed to capture plstrWindowName\n"); SetLastNtError(Status); - goto leave; + return NULL; } plstrWindowName = &lstrWindowName; } @@ -2603,6 +2314,7 @@ NtUserCreateWindowEx( Status = ProbeAndCaptureLargeString(&lstrClassName, plstrClassName); if (!NT_SUCCESS(Status)) { + DPRINT1("NtUserCreateWindowEx: failed to capture plstrClassName\n"); /* Set last error, cleanup and return */ SetLastNtError(Status); goto cleanup; @@ -2614,24 +2326,36 @@ NtUserCreateWindowEx( ustrClassName.MaximumLength = lstrClassName.MaximumLength; } - /* Call the internal function */ - pwnd = co_IntCreateWindowEx(dwExStyle, - &ustrClassName, - plstrWindowName, - dwStyle, - x, - y, - nWidth, - nHeight, - hWndParent, - hMenu, - hInstance, - lpParam, - SW_SHOW, - !(dwExStyle & WS_EX_SETANSICREATOR)); + /* Fill the CREATESTRUCTW */ + /* we will keep here the original parameters */ + Cs.style = dwStyle; + Cs.lpCreateParams = lpParam; + Cs.hInstance = hInstance; + Cs.hMenu = hMenu; + Cs.hwndParent = hWndParent; + Cs.cx = nWidth; + Cs.cy = nHeight; + Cs.x = x; + Cs.y = y; +// Cs.lpszName = (LPCWSTR) WindowName->Buffer; +// Cs.lpszClass = (LPCWSTR) ClassName->Buffer; + Cs.lpszName = (LPCWSTR) plstrWindowName; + Cs.lpszClass = (LPCWSTR) &ustrClassName; + Cs.dwExStyle = dwExStyle; + UserEnterExclusive(); + + /* Call the internal function */ + pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName); + + if(!pwnd) + { + DPRINT1("co_UserCreateWindowEx failed!\n"); + } hwnd = pwnd ? UserHMGetHandle(pwnd) : NULL; + UserLeave(); + cleanup: if (lstrWindowName.Buffer) { @@ -2642,10 +2366,6 @@ cleanup: ExFreePoolWithTag(lstrClassName.Buffer, TAG_STRING); } -leave: - DPRINT("Leave NtUserCreateWindowEx, hwnd=%i\n", hwnd); - UserLeave(); - return hwnd; } @@ -2674,6 +2394,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) PWND Wnd; HWND hWnd; PTHREADINFO ti; + MSG msg; ASSERT_REFS_CO(Window); // FIXME: temp hack? @@ -2779,7 +2500,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) Child = UserGetWindowObject(*ChildHandle); if (Child == NULL) continue; - if (Child->hOwner != Window->hSelf) + if (Child->spwndOwner != Window) { continue; } @@ -2795,9 +2516,9 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) continue; } - if (Child->hOwner != NULL) + if (Child->spwndOwner != NULL) { - Child->hOwner = NULL; + Child->spwndOwner = NULL; Child->Wnd->spwndOwner = NULL; } @@ -2811,6 +2532,13 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) } } + /* Generate mouse move message for the next window */ + msg.message = WM_MOUSEMOVE; + msg.wParam = IntGetSysCursorInfo()->ButtonsDown; + msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y); + msg.pt = gpsi->ptCursor; + MsqInsertSystemMessage(&msg); + if (!IntIsWindow(Window->hSelf)) { return TRUE; @@ -2952,11 +2680,11 @@ IntFindWindow(PWINDOW_OBJECT Parent, (Child->Wnd->strName.Length < 0xFFFF && !RtlCompareUnicodeString(WindowName, &CurrentWindowName, TRUE))) { - Ret = Child->hSelf; - break; - } + Ret = Child->hSelf; + break; } } + } ExFreePool(List); } @@ -3253,9 +2981,6 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type) break; } - //temp hack -// UserDereferenceObject(Parent); - WndAncestor = Parent; } break; @@ -3586,7 +3311,7 @@ BOOL APIENTRY NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) { PWINSTATION_OBJECT WinStaObject; - PWINDOW_OBJECT WndShell; + PWINDOW_OBJECT WndShell, WndListView; DECLARE_RETURN(BOOL); USER_REFERENCE_ENTRY Ref; NTSTATUS Status; @@ -3600,6 +3325,11 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) RETURN(FALSE); } + if(!(WndListView = UserGetWindowObject(hwndListView))) + { + RETURN(FALSE); + } + Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, KernelMode, 0, @@ -3633,14 +3363,14 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); #endif - if (UserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST) + if (WndListView->Wnd->ExStyle & WS_EX_TOPMOST) { ObDereferenceObject(WinStaObject); RETURN( FALSE); } } - if (UserGetWindowLong(hwndShell, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST) + if (WndShell->Wnd->ExStyle & WS_EX_TOPMOST) { ObDereferenceObject(WinStaObject); RETURN( FALSE); @@ -3765,162 +3495,6 @@ CLEANUP: END_CLEANUP; } -HWND FASTCALL -UserGetWindow(HWND hWnd, UINT Relationship) -{ - PWINDOW_OBJECT Parent, Window; - HWND hWndResult = NULL; - - if (!(Window = UserGetWindowObject(hWnd))) - return NULL; - - switch (Relationship) - { - case GW_HWNDFIRST: - if((Parent = Window->spwndParent)) - { - if (Parent->spwndChild) - hWndResult = Parent->spwndChild->hSelf; - } - break; - - case GW_HWNDLAST: - if((Parent = Window->spwndParent)) - { - if (Parent->spwndChild) - { - Window = Parent->spwndChild; - if(Window) - { - while(Window->spwndNext) - Window = Window->spwndNext; - } - hWndResult = Window->hSelf; - } - } - break; - - case GW_HWNDNEXT: - if (Window->spwndNext) - hWndResult = Window->spwndNext->hSelf; - break; - - case GW_HWNDPREV: - if (Window->spwndPrev) - hWndResult = Window->spwndPrev->hSelf; - break; - - case GW_OWNER: - if((Parent = UserGetWindowObject(Window->hOwner))) - { - hWndResult = Parent->hSelf; - } - break; - case GW_CHILD: - if (Window->spwndChild) - hWndResult = Window->spwndChild->hSelf; - break; - } - - return hWndResult; -} - -/* - * NtUserGetWindowLong - * - * The NtUserGetWindowLong function retrieves information about the specified - * window. The function also retrieves the 32-bit (long) value at the - * specified offset into the extra window memory. - * - * Status - * @implemented - */ - -LONG FASTCALL -UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) -{ - PWINDOW_OBJECT Window, Parent; - PWND Wnd; - LONG Result = 0; - - DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi); - - if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd) - { - return 0; - } - - Wnd = Window->Wnd; - - /* - * WndProc is only available to the owner process - */ - if (GWL_WNDPROC == Index - && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess()) - { - SetLastWin32Error(ERROR_ACCESS_DENIED); - return 0; - } - - if ((INT)Index >= 0) - { - if ((Index + sizeof(LONG)) > Window->Wnd->cbwndExtra) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - Result = *((LONG *)((PCHAR)(Window->Wnd + 1) + Index)); - } - else - { - switch (Index) - { - case GWL_EXSTYLE: - Result = Wnd->ExStyle; - break; - - case GWL_STYLE: - Result = Wnd->style; - break; - - case GWL_WNDPROC: - Result = (LONG)IntGetWindowProc(Wnd, Ansi); - break; - - case GWL_HINSTANCE: - Result = (LONG) Wnd->hModule; - break; - - case GWL_HWNDPARENT: - Parent = Window->spwndParent; - if(Parent) - { - if (Parent && Parent->hSelf == IntGetDesktopWindow()) - Result = (LONG) UserGetWindow(Window->hSelf, GW_OWNER); - else - Result = (LONG) Parent->hSelf; - } - break; - - case GWL_ID: - Result = (LONG) Wnd->IDMenu; - break; - - case GWL_USERDATA: - Result = Wnd->dwUserData; - break; - - default: - DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - Result = 0; - break; - } - } - - return Result; -} - LONG FASTCALL co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) { @@ -5019,7 +4593,7 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText) // In User32, these are called after: NotifyWinEvent EVENT_OBJECT_NAMECHANGE than // RepaintButton, StaticRepaint, NtUserCallHwndLock HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK, etc. /* Send shell notifications */ - if (!IntGetOwner(Window) && !IntGetParent(Window)) + if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd); } @@ -5120,11 +4694,10 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow ) count++; while (--count >= 0) { - if (UserGetWindow( win_array[count], GW_OWNER ) != OwnerWnd->hSelf) - continue; if (!(pWnd = UserGetWindowObject( win_array[count] ))) continue; - // if (pWnd == WND_OTHER_PROCESS) continue; + if (pWnd->spwndOwner != OwnerWnd) + continue; if (fShow) { diff --git a/subsystems/win32/win32k/ntuser/winpos.c b/subsystems/win32/win32k/ntuser/winpos.c index 67e5eadc92f..8bdd29969a3 100644 --- a/subsystems/win32/win32k/ntuser/winpos.c +++ b/subsystems/win32/win32k/ntuser/winpos.c @@ -151,7 +151,7 @@ co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window) } /* If this is popup window, try to activate the owner first. */ - if ((Wnd->style & WS_POPUP) && (WndTo = IntGetOwner(Window))) + if ((Wnd->style & WS_POPUP) && (WndTo = Window->spwndOwner)) { WndTo = UserGetAncestor( WndTo, GA_ROOT ); if (can_activate_window(WndTo)) goto done; @@ -741,11 +741,15 @@ HWND FASTCALL WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter) { HWND *List = NULL; - HWND Owner = UserGetWindow(hWnd, GW_OWNER); - LONG Style = UserGetWindowLong(hWnd, GWL_STYLE, FALSE); - PWINDOW_OBJECT DesktopWindow, ChildObject; + HWND Owner; + LONG Style; + PWINDOW_OBJECT Window ,DesktopWindow, ChildObject; int i; + Window = UserGetWindowObject(hWnd); + Owner = Window->spwndOwner ? Window->spwndOwner->hSelf : NULL; + Style = Window->Wnd->style; + if ((Style & WS_POPUP) && Owner) { /* Make sure this popup stays above the owner */ @@ -804,8 +808,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter) if (!(Wnd = UserGetWindowObject(List[i]))) continue; - if ((Wnd->Wnd->style & WS_POPUP) && - UserGetWindow(List[i], GW_OWNER) == hWnd) + if (Wnd->Wnd->style & WS_POPUP && Wnd->spwndOwner == Window) { USER_REFERENCE_ENTRY Ref; UserRefObjectCo(Wnd, &Ref); @@ -958,7 +961,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window) * itself. */ if ((WinPos->hwnd == WinPos->hwndInsertAfter) || - (WinPos->hwnd == UserGetWindow(WinPos->hwndInsertAfter, GW_HWNDNEXT))) + (WinPos->hwnd == InsAfterWnd->spwndNext->hSelf)) { WinPos->flags |= SWP_NOZORDER; } @@ -1463,6 +1466,33 @@ co_WinPosGetNonClientSize(PWINDOW_OBJECT Window, RECT* WindowRect, RECT* ClientR return Result; } +void FASTCALL +co_WinPosSendSizeMove(PWINDOW_OBJECT Window) +{ + WPARAM wParam = SIZE_RESTORED; + PWND Wnd = Window->Wnd; + + Window->state &= ~WINDOWOBJECT_NEED_SIZE; + if (Wnd->style & WS_MAXIMIZE) + { + wParam = SIZE_MAXIMIZED; + } + else if (Wnd->style & WS_MINIMIZE) + { + wParam = SIZE_MINIMIZED; + } + + co_IntSendMessageNoWait(Window->hSelf, WM_SIZE, wParam, + MAKELONG(Wnd->rcClient.right - + Wnd->rcClient.left, + Wnd->rcClient.bottom - + Wnd->rcClient.top)); + co_IntSendMessageNoWait(Window->hSelf, WM_MOVE, 0, + MAKELONG(Wnd->rcClient.left, + Wnd->rcClient.top)); + IntEngWindowChanged(Window, WOC_RGN_CLIENT); +} + BOOLEAN FASTCALL co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd) { @@ -1621,28 +1651,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd) if ((Window->state & WINDOWOBJECT_NEED_SIZE) && !(Window->state & WINDOWSTATUS_DESTROYING)) { - WPARAM wParam = SIZE_RESTORED; - - Window->state &= ~WINDOWOBJECT_NEED_SIZE; - if (Wnd->style & WS_MAXIMIZE) - { - wParam = SIZE_MAXIMIZED; - } - else if (Wnd->style & WS_MINIMIZE) - { - wParam = SIZE_MINIMIZED; - } - - co_IntSendMessageNoWait(Window->hSelf, WM_SIZE, wParam, - MAKELONG(Wnd->rcClient.right - - Wnd->rcClient.left, - Wnd->rcClient.bottom - - Wnd->rcClient.top)); - co_IntSendMessageNoWait(Window->hSelf, WM_MOVE, 0, - MAKELONG(Wnd->rcClient.left, - Wnd->rcClient.top)); - IntEngWindowChanged(Window, WOC_RGN_CLIENT); - + co_WinPosSendSizeMove(Window); } /* Activate the window if activation is not requested and the window is not minimized */ diff --git a/subsystems/win32/win32k/objects/cliprgn.c b/subsystems/win32/win32k/objects/cliprgn.c index c5297c38ba2..77415e686b6 100644 --- a/subsystems/win32/win32k/objects/cliprgn.c +++ b/subsystems/win32/win32k/objects/cliprgn.c @@ -60,24 +60,28 @@ CLIPPING_UpdateGCRegion(DC* Dc) NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y); - if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) - { - if (Dc->rosdc.CombinedClip != NULL) - IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); + if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) + { + CLIPOBJ *CombinedClip; + + CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount, + CombinedRegion->Buffer, + &CombinedRegion->rdh.rcBound); - Dc->rosdc.CombinedClip = IntEngCreateClipRegion( - CombinedRegion->rdh.nCount, - CombinedRegion->Buffer, - &CombinedRegion->rdh.rcBound); + RGNOBJAPI_Unlock(CombinedRegion); - RGNOBJAPI_Unlock(CombinedRegion); - } + if (!CombinedClip) + { + DPRINT1("IntEngCreateClipRegion() failed\n"); + return ERROR; + } + + if (Dc->rosdc.CombinedClip != NULL) + IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); + + Dc->rosdc.CombinedClip = CombinedClip; + } - if ( NULL == Dc->rosdc.CombinedClip ) - { - DPRINT1("IntEngCreateClipRegion() failed\n"); - return ERROR; - } return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y); } @@ -607,9 +611,6 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC) IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y); - if (pDC->rosdc.CombinedClip != NULL) - IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); - // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build // the rects from region objects rects in pClipRgn->Buffer. // With pDC->co.pClipRgn->Buffer, @@ -619,7 +620,13 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC) ((PROSRGNDATA)pDC->prgnRao)->Buffer, &pDC->erclClip); - pDC->rosdc.CombinedClip = co; + if (co) + { + if (pDC->rosdc.CombinedClip != NULL) + IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); + + pDC->rosdc.CombinedClip = co; + } return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y); } diff --git a/subsystems/win32/win32k/objects/device.c b/subsystems/win32/win32k/objects/device.c index b8d322f09ac..9ebe3a5ec28 100644 --- a/subsystems/win32/win32k/objects/device.c +++ b/subsystems/win32/win32k/objects/device.c @@ -1745,7 +1745,7 @@ IntEnumDisplaySettings( } while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd) { - assert(CachedMode->dmSize > 0); + ASSERT(CachedMode->dmSize > 0); CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra); } if (CachedMode >= CachedDevModesEnd) diff --git a/subsystems/win32/win32k/objects/fillshap.c b/subsystems/win32/win32k/objects/fillshap.c index aa133f87f52..327b628ed30 100644 --- a/subsystems/win32/win32k/objects/fillshap.c +++ b/subsystems/win32/win32k/objects/fillshap.c @@ -837,40 +837,36 @@ NtGdiRoundRect( return ret; } -BOOL FASTCALL -IntGdiGradientFill( - DC *dc, +BOOL +NTAPI +GreGradientFill( + HDC hdc, PTRIVERTEX pVertex, - ULONG uVertex, + ULONG nVertex, PVOID pMesh, - ULONG uMesh, + ULONG nMesh, ULONG ulMode) { + PDC pdc; SURFACE *psurf; - PPALETTE PalDestGDI; + PPALETTE ppal; EXLATEOBJ exlo; - RECTL Extent; - POINTL DitherOrg; + RECTL rclExtent; + POINTL ptlDitherOrg; ULONG i; - BOOL Ret; + BOOL bRet; HPALETTE hDestPalette; - ASSERT(dc); - ASSERT(pVertex); - ASSERT(uVertex); - ASSERT(pMesh); - ASSERT(uMesh); - - /* check parameters */ - if (ulMode & GRADIENT_FILL_TRIANGLE) + /* Check parameters */ + if (ulMode == GRADIENT_FILL_TRIANGLE) { - PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh; + PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh; - for (i = 0; i < uMesh; i++, tr++) + for (i = 0; i < nMesh; i++, pTriangle++) { - if (tr->Vertex1 >= uVertex || - tr->Vertex2 >= uVertex || - tr->Vertex3 >= uVertex) + if (pTriangle->Vertex1 >= nVertex || + pTriangle->Vertex2 >= nVertex || + pTriangle->Vertex3 >= nVertex) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; @@ -879,10 +875,10 @@ IntGdiGradientFill( } else { - PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh; - for (i = 0; i < uMesh; i++, rc++) + PGRADIENT_RECT pRect = (PGRADIENT_RECT)pMesh; + for (i = 0; i < nMesh; i++, pRect++) { - if (rc->UpperLeft >= uVertex || rc->LowerRight >= uVertex) + if (pRect->UpperLeft >= nVertex || pRect->LowerRight >= nVertex) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; @@ -890,56 +886,78 @@ IntGdiGradientFill( } } - /* calculate extent */ - Extent.left = Extent.right = pVertex->x; - Extent.top = Extent.bottom = pVertex->y; - for (i = 0; i < uVertex; i++) + /* Lock the output DC */ + pdc = DC_LockDc(hdc); + if (!pdc) { - Extent.left = min(Extent.left, (pVertex + i)->x); - Extent.right = max(Extent.right, (pVertex + i)->x); - Extent.top = min(Extent.top, (pVertex + i)->y); - Extent.bottom = max(Extent.bottom, (pVertex + i)->y); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; } - IntLPtoDP(dc, (LPPOINT)&Extent, 2); - Extent.left += dc->ptlDCOrig.x; - Extent.right += dc->ptlDCOrig.x; - Extent.top += dc->ptlDCOrig.y; - Extent.bottom += dc->ptlDCOrig.y; + if (pdc->dctype == DC_TYPE_INFO) + { + DC_UnlockDc(pdc); + /* Yes, Windows really returns TRUE in this case */ + return TRUE; + } - DitherOrg.x = DitherOrg.y = 0; - IntLPtoDP(dc, (LPPOINT)&DitherOrg, 1); + psurf = pdc->dclevel.pSurface; + if (!psurf) + { + /* Memory DC with no surface selected */ + DC_UnlockDc(pdc); + return TRUE; // CHECKME + } - DitherOrg.x += dc->ptlDCOrig.x; - DitherOrg.y += dc->ptlDCOrig.y; + /* calculate extent */ + rclExtent.left = rclExtent.right = pVertex->x; + rclExtent.top = rclExtent.bottom = pVertex->y; + for (i = 0; i < nVertex; i++) + { + rclExtent.left = min(rclExtent.left, (pVertex + i)->x); + rclExtent.right = max(rclExtent.right, (pVertex + i)->x); + rclExtent.top = min(rclExtent.top, (pVertex + i)->y); + rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y); + } - psurf = dc->dclevel.pSurface; - /* FIXME - psurf can be NULL!!! Don't assert but handle this case gracefully! */ - ASSERT(psurf); + IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2); + rclExtent.left += pdc->ptlDCOrig.x; + rclExtent.right += pdc->ptlDCOrig.x; + rclExtent.top += pdc->ptlDCOrig.y; + rclExtent.bottom += pdc->ptlDCOrig.y; + + ptlDitherOrg.x = ptlDitherOrg.y = 0; + IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1); + ptlDitherOrg.x += pdc->ptlDCOrig.x; + ptlDitherOrg.y += pdc->ptlDCOrig.y; hDestPalette = psurf->hDIBPalette; if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault; - PalDestGDI = PALETTE_LockPalette(hDestPalette); - EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalDestGDI, 0, 0, 0); + ppal = PALETTE_LockPalette(hDestPalette); + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0); - Ret = IntEngGradientFill(&psurf->SurfObj, - dc->rosdc.CombinedClip, - &exlo.xlo, - pVertex, - uVertex, - pMesh, - uMesh, - &Extent, - &DitherOrg, - ulMode); + ASSERT(pdc->rosdc.CombinedClip); + + bRet = IntEngGradientFill(&psurf->SurfObj, + pdc->rosdc.CombinedClip, + &exlo.xlo, + pVertex, + nVertex, + pMesh, + nMesh, + &rclExtent, + &ptlDitherOrg, + ulMode); EXLATEOBJ_vCleanup(&exlo); - if (PalDestGDI) - PALETTE_UnlockPalette(PalDestGDI); + if (ppal) + PALETTE_UnlockPalette(ppal); - return Ret; + DC_UnlockDc(pdc); + + return bRet; } BOOL @@ -947,33 +965,19 @@ APIENTRY NtGdiGradientFill( HDC hdc, PTRIVERTEX pVertex, - ULONG uVertex, + ULONG nVertex, PVOID pMesh, - ULONG uMesh, + ULONG nMesh, ULONG ulMode) { - DC *dc; - BOOL Ret; + BOOL bRet; PTRIVERTEX SafeVertex; PVOID SafeMesh; - ULONG SizeMesh; - NTSTATUS Status = STATUS_SUCCESS; + ULONG cbVertex, cbMesh; - dc = DC_LockDc(hdc); - if (!dc) + /* Validate parameters */ + if (!pVertex || !nVertex || !pMesh || !nMesh) { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - if (dc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(dc); - /* Yes, Windows really returns TRUE in this case */ - return TRUE; - } - if (!pVertex || !uVertex || !pMesh || !uMesh) - { - DC_UnlockDc(dc); SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } @@ -982,77 +986,55 @@ NtGdiGradientFill( { case GRADIENT_FILL_RECT_H: case GRADIENT_FILL_RECT_V: - SizeMesh = uMesh * sizeof(GRADIENT_RECT); + cbMesh = nMesh * sizeof(GRADIENT_RECT); break; case GRADIENT_FILL_TRIANGLE: - SizeMesh = uMesh * sizeof(TRIVERTEX); + cbMesh = nMesh * sizeof(GRADIENT_TRIANGLE); break; default: - DC_UnlockDc(dc); SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; } - _SEH2_TRY + cbVertex = nVertex * sizeof(TRIVERTEX); + if (cbVertex + cbMesh <= cbVertex) { - ProbeForRead(pVertex, - uVertex * sizeof(TRIVERTEX), - 1); - ProbeForRead(pMesh, - SizeMesh, - 1); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) - { - DC_UnlockDc(dc); - SetLastWin32Error(Status); + /* Overflow */ return FALSE; } - if (!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE))) + /* Allocate a kernel mode buffer */ + SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE); + if (!SafeVertex) { - DC_UnlockDc(dc); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex); + SafeMesh = (PVOID)((ULONG_PTR)SafeVertex + cbVertex); + /* Copy the parameters to kernel mode */ _SEH2_TRY { - /* pointers were already probed! */ - RtlCopyMemory(SafeVertex, - pVertex, - uVertex * sizeof(TRIVERTEX)); - RtlCopyMemory(SafeMesh, - pMesh, - SizeMesh); + ProbeForRead(pVertex, cbVertex, 1); + ProbeForRead(pMesh, cbMesh, 1); + RtlCopyMemory(SafeVertex, pVertex, cbVertex); + RtlCopyMemory(SafeMesh, pMesh, cbMesh); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); + ExFreePoolWithTag(SafeVertex, TAG_SHAPE); + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(return FALSE;) } _SEH2_END; - if (!NT_SUCCESS(Status)) - { - DC_UnlockDc(dc); - ExFreePoolWithTag(SafeVertex, TAG_SHAPE); - SetLastNtError(Status); - return FALSE; - } + /* Call the internal function */ + bRet = GreGradientFill(hdc, SafeVertex, nVertex, SafeMesh, nMesh, ulMode); - Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode); - - DC_UnlockDc(dc); - ExFreePool(SafeVertex); - return Ret; + /* Cleanup and return result */ + ExFreePoolWithTag(SafeVertex, TAG_SHAPE); + return bRet; } BOOL APIENTRY diff --git a/subsystems/win32/win32k/objects/icm.c b/subsystems/win32/win32k/objects/icm.c index dd99ea3d89d..f0d7ef72e7a 100644 --- a/subsystems/win32/win32k/objects/icm.c +++ b/subsystems/win32/win32k/objects/icm.c @@ -146,7 +146,7 @@ NtGdiGetDeviceGammaRamp(HDC hDC, return FALSE; } - SafeRamp = ExAllocatePool(PagedPool, sizeof(GAMMARAMP)); + SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM); if (!SafeRamp) { DC_UnlockDc(dc); @@ -174,7 +174,7 @@ NtGdiGetDeviceGammaRamp(HDC hDC, _SEH2_END; DC_UnlockDc(dc); - ExFreePool(SafeRamp); + ExFreePoolWithTag(SafeRamp, TAG_GDIICM); if (!NT_SUCCESS(Status)) { @@ -377,7 +377,7 @@ NtGdiSetDeviceGammaRamp(HDC hDC, return FALSE; } - SafeRamp = ExAllocatePool(PagedPool, sizeof(GAMMARAMP)); + SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM); if (!SafeRamp) { DC_UnlockDc(dc); @@ -402,14 +402,14 @@ NtGdiSetDeviceGammaRamp(HDC hDC, if (!NT_SUCCESS(Status)) { DC_UnlockDc(dc); - ExFreePool(SafeRamp); + ExFreePoolWithTag(SafeRamp, TAG_GDIICM); SetLastNtError(Status); return FALSE; } Ret = IntSetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp, TRUE); DC_UnlockDc(dc); - ExFreePool(SafeRamp); + ExFreePoolWithTag(SafeRamp, TAG_GDIICM); return Ret; } diff --git a/subsystems/win32/win32k/objects/palette.c b/subsystems/win32/win32k/objects/palette.c index 8fcbbe4077c..e108b5c6885 100644 --- a/subsystems/win32/win32k/objects/palette.c +++ b/subsystems/win32/win32k/objects/palette.c @@ -61,9 +61,6 @@ HPALETTE FASTCALL PALETTE_Init(VOID) int i; HPALETTE hpalette; PLOGPALETTE palPtr; -#ifndef NO_MAPPING - PALOBJ *palObj; -#endif // create default palette (20 system colors) palPtr = ExAllocatePoolWithTag(PagedPool, @@ -85,19 +82,6 @@ HPALETTE FASTCALL PALETTE_Init(VOID) hpalette = NtGdiCreatePaletteInternal(palPtr,NB_RESERVED_COLORS); ExFreePoolWithTag(palPtr, TAG_PALETTE); -#ifndef NO_MAPPING - palObj = (PALOBJ*)PALETTE_LockPalette(hpalette); - if (palObj) - { - if (!(palObj->mapping = ExAllocatePool(PagedPool, sizeof(int) * 20))) - { - DbgPrint("Win32k: Can not create palette mapping -- out of memory!"); - return FALSE; - } - PALETTE_UnlockPalette(palObj); - } -#endif - /* palette_size = visual->map_entries; */ gpalRGB.Mode = PAL_RGB; @@ -232,7 +216,7 @@ PALETTE_Cleanup(PVOID ObjectBody) PPALETTE pPal = (PPALETTE)ObjectBody; if (NULL != pPal->IndexedColors) { - ExFreePool(pPal->IndexedColors); + ExFreePoolWithTag(pPal->IndexedColors, TAG_PALETTE); } return TRUE; @@ -453,7 +437,7 @@ NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries ) else { /* FIXME - Handle PalGDI == NULL!!!! */ - DPRINT1("waring PalGDI is NULL \n"); + DPRINT1("PalGDI is NULL\n"); } return NewPalette; } @@ -981,7 +965,7 @@ NtGdiDoPalette( if (pUnsafeEntries) { - pEntries = ExAllocatePool(PagedPool, cEntries * sizeof(PALETTEENTRY)); + pEntries = ExAllocatePoolWithTag(PagedPool, cEntries * sizeof(PALETTEENTRY), TAG_PALETTE); if (!pEntries) return 0; if (bInbound) @@ -993,7 +977,7 @@ NtGdiDoPalette( } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - ExFreePool(pEntries); + ExFreePoolWithTag(pEntries, TAG_PALETTE); _SEH2_YIELD(return 0); } _SEH2_END @@ -1047,7 +1031,7 @@ NtGdiDoPalette( } _SEH2_END } - ExFreePool(pEntries); + ExFreePoolWithTag(pEntries, TAG_PALETTE); } return ret; diff --git a/subsystems/win32/win32k/w32ksvc.db b/subsystems/win32/win32k/w32ksvc.db index acce60122d2..0b90145a90f 100644 --- a/subsystems/win32/win32k/w32ksvc.db +++ b/subsystems/win32/win32k/w32ksvc.db @@ -684,7 +684,6 @@ NtGdiOffsetWindowOrgEx 4 # NtUserBuildMenuItemList 4 NtUserCreateCursorIconHandle 2 -NtUserGetClassLong 3 NtUserGetMenuDefaultItem 3 NtUserGetLastInputInfo 1 NtUserGetMinMaxInfo 3